欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript原型Prototype詳情

 更新時(shí)間:2021年12月06日 10:31:36   作者:一碗周  
這篇文章主要介紹了JavaScript原型Prototype,在JavaScript中,函數(shù)是一個(gè)包含屬性和方法的Function類型的對(duì)象。而原型(Prototype?)就是Function類型對(duì)象的一個(gè)屬性。具體內(nèi)容需要的朋友可以參考下面文章的介紹

1、概述

1.1原型是什么

JavaScript中,函數(shù)是一個(gè)包含屬性和方法的Function類型的對(duì)象。而原型(Prototype )就是Function類型對(duì)象的一個(gè)屬性。

在函數(shù)定義是包含了prototype屬性,它的初始值是一個(gè)空對(duì)象 。在JavaScript中并沒(méi)有定義函數(shù)的原始類型,所以原型可以是任何類型。

原型是用于保存對(duì)象的共享屬性和方法的,原型的屬性和方法并不會(huì)影響函數(shù)本身的屬性和方法。

示例代碼驗(yàn)證如下:

function fun() {
  console.log('函數(shù)原型')
}
console.log(fun.prototype) // {}

fun.prototype返回的也是一個(gè)空對(duì)象,但是這不說(shuō)明Object.prototype中沒(méi)有屬性或者方法,這些屬性和方法為不可枚舉的,示例代碼如下所示:

function fun() {
  console.log('函數(shù)原型')
}

console.log(fun.prototype) // {}
// 通過(guò) Object.getOwnPropertyNames() 獲取全部屬性
console.log(Object.getOwnPropertyNames(fun.prototype)) // [ 'constructor' ]

其中,constructor屬性指向該構(gòu)造函數(shù)的引用,代碼如下:

// constructor屬性

console.log(fun.prototype.constructor) // [Function: fun]

console.log(fun.prototype.constructor === fun) // true

1.2獲取原型

了解了原型的概念以及作用之后,我們需要獲取到原型才能對(duì)其進(jìn)行操作,在JavaScript中獲取原型的方式有兩種,如下所示:

通過(guò)構(gòu)造函數(shù)的prototype屬性。

通過(guò)Object.getPrototypeOf(obj)方法。

這兩個(gè)的區(qū)別就是構(gòu)造函數(shù)的prototype屬性一般只配合構(gòu)造函數(shù)使用,而Object.getPrototypeOf(obj)方法一般是獲取構(gòu)造函數(shù)實(shí)例化后的對(duì)象的原型方法。

實(shí)例代碼如下:

// 構(gòu)造函數(shù)
function Person(name) {
  this.name = name
}

// 指向構(gòu)造函數(shù)的原型
var p1 = Person.prototype

var person = new Person('一碗周')

// 指向構(gòu)造函數(shù)的原型
var p2 = Object.getPrototypeOf(person)

console.log(p1 === p2) // true

獲取原型后可以跟操作對(duì)象似的進(jìn)行操作,因?yàn)樵捅旧砭褪且粋€(gè)對(duì)象。

2、原型屬性

JavaScript中,函數(shù)本身也是一個(gè)包含了方法和屬性的對(duì)象。接下將學(xué)習(xí)函數(shù)對(duì)象的另一個(gè)屬性——prototype,這個(gè)屬性的初始值是一個(gè)空對(duì)象。

2.1利用原型添加屬性與方法。

為對(duì)象添加屬性和方法的另一種用法就是通過(guò)原型為其添加。當(dāng)為一個(gè)構(gòu)造函數(shù)添加原型屬性和原型方法時(shí),通過(guò)該構(gòu)造函數(shù)new出的所有對(duì)象共享該屬性和方法。

PS:所謂的原型屬性或者原型方法就是通過(guò)原型添加的屬性或者方法。

添加屬性和方法的方式具有如下幾種方式

直接為其增加屬性或者方法

通過(guò)Object.defineProperty()方法,添加屬性或者方法。這種方式比第一種方式更具有安全性。

直接添加對(duì)象到原型。

示例代碼如下所示:

//構(gòu)造函數(shù)
function Fun() {}
//直接為構(gòu)造函數(shù)添加屬性和方法
Fun.prototype.str = '這是一個(gè)字符串'
Fun.prototype.fn = function () {
  console.log('這是一個(gè)方法')
}
//通過(guò) defineProperty 添加屬性或者方法
Object.defineProperty(Fun.prototype, 'MyFun', {
  value: function () {
    console.log('this is MyFun')
  },
})
//測(cè)試
console.log(Fun.prototype.str)
Fun.prototype.fn()
Fun.prototype.MyFun()
var fun = new Fun()
fun.MyFun()
//直接為其定義個(gè)對(duì)象覆蓋到之前的原型上
Fun.prototype = {
  name: '一碗周',
  fun: function () {
    console.log('this is function')
  },
}
Fun.prototype.fun()
var fun = new Fun()
fun.fun()

2.2訪問(wèn)原型屬性原型方法

對(duì)于原型來(lái)說(shuō),最重要的一點(diǎn)就是它的實(shí)時(shí)性 。由于在JavaScript中,幾乎所有的對(duì)象都是通過(guò)傳引用的方式來(lái)傳遞的,因此我們所創(chuàng)建的的每個(gè)新對(duì)象實(shí)體中并沒(méi)有一份屬于自己的原型副本。這就意味著我們隨時(shí)修改prototype屬性,并且由同一構(gòu)造器創(chuàng)建的所有對(duì)象的prototype屬性也都會(huì)同時(shí)改變,包括我們之間通過(guò)構(gòu)造器創(chuàng)建的屬性和方法。

還是上面那段代碼我們向原型中添加一個(gè)新方法,并調(diào)用,示例代碼如下所示:

Fun.prototype.fn = function () {
  console.log('這是一個(gè)方法')
}
fun.fn() //這是一個(gè)方法

我們之前創(chuàng)建的對(duì)象可以訪問(wèn)新加的原型屬性和原型方法。

3、自有屬性與原型屬性

我們先來(lái)創(chuàng)建一個(gè)構(gòu)造函數(shù),并為其添加兩個(gè)原型屬性。

//構(gòu)造函數(shù)
function Fun() {}
//添加原型屬性和方法
Fun.prototype.name = '一碗粥'
Fun.prototype.print = function () {
  console.log('this is function')
}

在通過(guò)該構(gòu)造函數(shù)創(chuàng)建一個(gè)對(duì)象,為其設(shè)置屬性和方法

//通過(guò)構(gòu)造函數(shù)創(chuàng)建對(duì)象
var fun = new Fun()
//為對(duì)象添加屬性和方法
fun.name = '一碗周'
fun.SayMe = function () {
  console.log('this is SayMe')
}

現(xiàn)在我們的fun對(duì)象,擁有自有屬性/方法兩個(gè),原型屬性/方法兩個(gè)。我們依次來(lái)訪問(wèn)這些屬性和方法。

//訪問(wèn)屬性和方法
console.log(fun.name) // 一碗周
fun.SayMe() // this is SayMe
fun.print() // this is function


當(dāng)我們?cè)L問(wèn)name屬性時(shí),JavaScript引擎會(huì)遍歷fun這個(gè)對(duì)象的所有屬性,并返回name屬性的值。SayMe()方法也是樣的道理。但是到print()方法時(shí),JavaScript引擎還是會(huì)遍歷這個(gè)對(duì)象所有屬性,這時(shí)就找不到一個(gè)叫print()方法了,接下來(lái)JavaScript引擎就會(huì)訪問(wèn)創(chuàng)建當(dāng)前對(duì)象的構(gòu)造器函數(shù)的原型,也就是我們的Fun.prototype,如果其中有該屬性,則立即返回,否則返回undefined或者拋出異常

結(jié)論:當(dāng)有自有屬性時(shí),優(yōu)先訪問(wèn)自有屬性,訪問(wèn)完自有屬性再去訪問(wèn)原型屬性 。

3.1檢測(cè)自有屬性或者原型屬性

現(xiàn)在已經(jīng)知道自有屬性和原型屬性的概念以及用途了,但是我們?cè)趺粗酪粋€(gè)屬性時(shí)自由屬性還是原有屬性,JavaScript中提供以下兩種方式來(lái)檢測(cè)一個(gè)屬性的情況

使用Object.prototype.hasOwnProperty(prop)方法來(lái)檢測(cè)prop屬性是否是自由屬性,該方法返回一個(gè)布爾值,如果是自有屬性則返回true,否則返回false。

來(lái)使用in關(guān)鍵字來(lái)檢測(cè)對(duì)象以及原型鏈中是否具有指定屬性。

測(cè)試代碼如下:

// 通過(guò)Object.prototype.hasOwnProperty(prop)方法檢測(cè)是否為自有屬性
console.log(fun.hasOwnProperty('name')) // true
console.log(fun.hasOwnProperty('print')) // false
// 如果一個(gè)不存在的屬性檢測(cè)結(jié)果也是為false
console.log(fun.hasOwnProperty('SayMe')) // true

// 通過(guò) in 運(yùn)算符
console.log('name' in fun) // true
console.log('print' in fun) // true
console.log('SayMe' in fun) // true

通過(guò)測(cè)試我們發(fā)現(xiàn),這兩個(gè)方法并不能檢測(cè)一個(gè)屬性是不是一個(gè)自有屬性或者原型屬性,但是將這兩個(gè)方法結(jié)合起來(lái)就可以檢測(cè)是自有屬性還是原型屬性了,

示例代碼如下:

function DetectionAttributes(obj, attr) {
  if (attr in obj) {
    if (obj.hasOwnProperty(attr)) {
      // 如果是自有屬性屬性返回1
      return 1
    } else {
      // 如果是原型屬性返回0
      return 0
    }
  } else {
    // 沒(méi)有這個(gè)屬性返回 -1
    return -1
  }
}


測(cè)試如下:

console.log(DetectionAttributes(fun, 'name')) // 1
console.log(DetectionAttributes(fun, 'print')) // 0
console.log(DetectionAttributes(fun, 'SayMe')) // 1

4、isPrototypeOf()方法

isPrototypeOf()方法用來(lái)檢測(cè)一個(gè)對(duì)象是否存在于另一個(gè)對(duì)象的原型鏈中,如果存在就返回true,否則就返回false。

實(shí)例代碼如下所示:

// 定義一個(gè)對(duì)象,用于賦值給原型對(duì)象
var obj = function () {
  this.name = '一碗周'
}
var Hero = function () {} // 定義構(gòu)造函數(shù)
// 將定義的對(duì)象賦值給構(gòu)造函數(shù)的原型
Hero.prototype = obj

// 通過(guò)Hero創(chuàng)建對(duì)象
var hero1 = new Hero()
var hero2 = new Hero()
// 判斷創(chuàng)建的兩個(gè)對(duì)象是否在 obj 的原型鏈中
console.log(obj.isPrototypeOf(hero1)) // true
console.log(obj.isPrototypeOf(hero2)) // true

5、擴(kuò)展內(nèi)置對(duì)象

JavaScript中的內(nèi)置對(duì)象有些也具prototype屬性,利用內(nèi)置對(duì)象的prototype屬性可以為內(nèi)置對(duì)象擴(kuò)展屬性和方法。

通過(guò)原型擴(kuò)展內(nèi)置對(duì)象的屬性和方法非常靈活,根據(jù)個(gè)性化要求制定JavaScript語(yǔ)言的具體內(nèi)容。

擴(kuò)展內(nèi)置對(duì)象的方式有兩種,具體如下所示:

通過(guò)直接新增屬性和方法。

通過(guò)Object對(duì)象的defineProperty()方法為其新增屬性或者方法。這種方式會(huì)比第一種方式要好,是創(chuàng)建的屬性和方法更具有安全性

示例代碼如下所示:

// 為 Object 擴(kuò)展屬性和方法
// 使用第一種方式
Object.prototype.MyPrint = function () {
  console.log('this is MyPrint()')
}
// 使用第二種方式
Object.defineProperty(Object.prototype, 'MyInput', {
  value: function () {
    console.log('this is MyInput()')
  },
})
// 調(diào)用
Object.prototype.MyPrint() // this is MyPrint()
Object.prototype.MyInput() // this is MyInput()

6、結(jié)語(yǔ)

這篇文章介紹了JavaScript中的原型的概念、原型屬性、如何檢測(cè)自有屬性和原型屬性以及如何擴(kuò)展內(nèi)置對(duì)象

到此這篇關(guān)于JavaScript原型Prototype詳情的文章就介紹到這了,更多相關(guān)JavaScript原型內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論