1. 程式人生 > 其它 >原型和原型鏈以及call和apply

原型和原型鏈以及call和apply

技術標籤:jsjavascript指標prototype

一、原型

1. prototype

原型是 function 物件的一個屬性,它定義了建構函式製造出的物件的公共祖先。通過該建構函式產生的物件,可以繼承該原型的屬性和方法。原型也是物件

可能大家對這個定義不太理解,下面我們來舉一個例子:

//Person.prototype   --原型
//該原型在建構函式建立的時候就被定義好了,為一個屬性,是祖先
//Person.prototype = {}
Person.prototype.name = "alex";
function Person(){}

let p = new
Person() console.log(p.name) //輸出alex

上面程式碼中我建立了一個建構函式,但是裡面我並沒有傳值,按理說什麼都不會輸出,但是像原型的定義說的,prototype是構造出的物件的祖先,該物件會繼承該原型的屬性和方法。

prototype 這個屬性是一個指標,指向一個物件,而這個物件的用途是包含可以有特定型別的所有例項共享的屬性和方法。prototype是通過呼叫建構函式而建立的那個物件例項的原型物件。

2. _ proto _

物件具有屬性__proto__,可稱為隱式原型,一個物件的隱式原型指向構造該物件的建構函式的原型,這也保證了例項能夠訪問在建構函式原型中定義的屬性和方法。

Person.prototype.name = "alex";
function Person(){}

let p = new Person()

console.log(p)   
console.log(p.__proto__)

輸出結果
在這裡插入圖片描述
構造出來的p物件指向Person,然後裡面有個__proto__屬性,而 nameconstructor 等屬性都在__proto__屬性中。

接下來我們再看一個例子:

function Foo(){}
var Boo = {name: "Boo"};
Foo.prototype = Boo;
var
f = new Foo(); console.log(f.__proto__ === Foo.prototype); // true console.log(f.__proto__ === Boo); // true Object.getPrototypeOf(f) === f.__proto__; // true

3. prototype 和 __ proto __ 的區別

__proto__每個物件都有的一個屬性,而 prototype函式才會有的屬性

使用 Object.getPrototypeOf() 可以代替 __proto__

4. 原型鏈

這家寫的挺好

5. call() 和 apply()

每個函式都包含兩個非繼承而來的方法:apply()call()

callapply 都屬於Function.prototype的一個方法,所以每個function例項都有callapply屬性

① 作用:改變this的指向

② 區別:接收引數的方式不同

  • call():第一個引數是 this 值沒有變化,變化的是其餘引數都直接傳遞給函式。在使用call()方法時,傳遞給函式的引數必須逐個列舉出來。
  • apply():傳遞給函式的是引數陣列
function add(c, d){ 
    return this.a + this.b + c + d; 
} 
var o = {a:1, b:3}; 
add.call(o, 5, 7); // 1 + 3 + 5 + 7 = 16 
add.apply(o, [10, 20]); // 1 + 3 + 10 + 20 = 34