定義
原型是function對(duì)象的一個(gè)屬性它定義了構(gòu)造函數(shù)制造出的對(duì)象的公共祖先。通過該構(gòu)造函數(shù)產(chǎn)生的對(duì)象泵督,可以繼承該原型的屬性和方法趾盐。原型也是對(duì)象。
// Person.prototype --原型
// Person.prototype={} 是祖先
Person.prototype.name='hehe'; //共有的
function Person(){
}
var person=new Person();//hehe
var person1=new Person();//hehe
特點(diǎn):可以繼承該原型的屬性和方法小腊。
// Person.prototype --原型
// Person.prototype={} 是祖先
Person.prototype.height=1400;
Person.prototype.lang=4900;
Person.prototype.carName='BMW';
function Person(color,owner){
this.owner=owner;
this.color=color;
}
var person=new Person('red','prof.ji'); //Person.carName='BMW'
var person1=new Person('green','laodeng');//Person.carName='BMW'
如何構(gòu)成原型鏈;
原型鏈上屬性的增刪改查
絕大多數(shù)對(duì)象的最終都會(huì)繼承自O(shè)bject.prototype
Object.create(原型)
function Person(){
}
Person.prototype
//打印出
Object{};
//里面有的屬性
constructor : Person();
__proto__ : Object;
//我們發(fā)現(xiàn)在prototype里面,他還有原型,說明原型他還有原型
原型鏈上的增刪改查和原型上的差不多,只能在自己的身上改,沒有辦法修改父級(jí)上面的…但是也不是完全不可以
最終原型
Grand.prototype.name = "shen"
function Grand(){
}
var grand = new Grand;
Father.prototype = grand;
function Father(){
}
var father = new Father;
son.prototype = father;
function son(){
}
var son = new Son();
son.name//打印出shen
//依次排查
Grand.prototype.__proto__ = object.prototype
//object.prototype最終原型
Object.create : 就是一個(gè)新的對(duì)象可以繼承一個(gè)對(duì)象的屬性救鲤,并且可以自行添加屬性
//var Obj = Object.create(原型)
var Obj = {
name = "sunny",
age : 123
};
var obj1 = Object.create(obj);
obj1.name//打印出sunny
添加屬性
var parents = {
name : "wu",
bron : "2013",
from : "China"
}
var child = Object.create(
parents,
{
title : {
value : "技術(shù)分享",
},
year : {
value : "18",
}
}
);
特殊情況
var a = object.create(null)
//這種情況他就沒有原型
call\apply\bind
JavaScript 提供了call、apply秩冈、bind這三個(gè)方法本缠,來切換/固定this的指向。
作用,改變this指向;
區(qū)別,后面?zhèn)鞯膮?shù)不同
function Person(name,age){
//this == obj;
this.name = name;
this.age = age;
}
var person = new Person("shen" 150);
var obj = {};
Person.call(obj,"wu",200);
函數(shù)實(shí)例的call方法入问,可以指定函數(shù)內(nèi)部this的指向(即函數(shù)執(zhí)行時(shí)所在的作用域)搓茬,然后在所指定的作用域中犹赖,調(diào)用該函數(shù)
var obj = {};
var f = function () {
return this;
};
f() === window // true
f.call(obj) === obj // true
上面代碼中队他,全局環(huán)境運(yùn)行函數(shù)f時(shí)卷仑,this指向全局環(huán)境(瀏覽器為window對(duì)象);call方法可以改變this的指向麸折,指定this指向?qū)ο髈bj锡凝,然后在對(duì)象obj的作用域中運(yùn)行函數(shù)f
var n = 123;
var obj = { n: 456 };
funcion a() {
console.log(this.n);
}
a.call() // 123
a.call(null) // 123
a.call(undefined) // 123
a.call(window) // 123
a.call(obj) // 456
上面代碼中,a函數(shù)中的this關(guān)鍵字垢啼,如果指向全局對(duì)象窜锯,返回結(jié)果為123。如果使用call方法將this關(guān)鍵字指向obj對(duì)象芭析,返回結(jié)果為456锚扎。可以看到馁启,如果call方法沒有參數(shù)驾孔,或者參數(shù)為null或undefined,則等同于指向全局對(duì)象
Function.prototype.apply()
apply方法的作用與call方法類似惯疙,也是改變this指向翠勉,然后再調(diào)用該函數(shù)。唯一的區(qū)別就是霉颠,它接收一個(gè)數(shù)組作為函數(shù)執(zhí)行時(shí)的參數(shù)对碌,使用格式如下。
func.apply(thisValue, [arg1, arg2, ...])
apply方法的第一個(gè)參數(shù)也是this所要指向的那個(gè)對(duì)象蒿偎,如果設(shè)為null或undefined朽们,則等同于指定全局對(duì)象。第二個(gè)參數(shù)則是一個(gè)數(shù)組诉位,該數(shù)組的所有成員依次作為參數(shù)骑脱,傳入原函數(shù)。原函數(shù)的參數(shù)不从,在call方法中必須一個(gè)個(gè)添加惜姐,但是在apply方法中琴拧,必須以數(shù)組形式添加
function f(x, y){
console.log(x + y);
}
f.call(null, 1, 1) // 2
f.apply(null, [1, 1]) // 2
上面代碼中屈溉,f函數(shù)本來接受兩個(gè)參數(shù)典奉,使用apply方法以后最爬,就變成可以接受一個(gè)數(shù)組作為參數(shù)
Function.prototype.bind()
bind方法用于將函數(shù)體內(nèi)的this綁定到某個(gè)對(duì)象肚医,然后返回一個(gè)新函數(shù)
var d = new Date();
d.getTime() // 1481869925657
var print = d.getTime;
print() // Uncaught TypeError: this is not a Date object.
上面代碼中匙奴,我們將d.getTime方法賦給變量print叙赚,然后調(diào)用print就報(bào)錯(cuò)了怨咪。這是因?yàn)間etTime方法內(nèi)部的this乏矾,綁定Date對(duì)象的實(shí)例孟抗,賦給變量print以后迁杨,內(nèi)部的this已經(jīng)不指向Date對(duì)象的實(shí)例了
bind方法可以解決這個(gè)問題。
var print = d.getTime.bind(d);
print() // 1481869925657
上面代碼中凄硼,bind方法將getTime方法內(nèi)部的this綁定到d對(duì)象铅协,這時(shí)就可以安全地將這個(gè)方法賦值給其他變量了。
bind方法的參數(shù)就是所要綁定this的對(duì)象摊沉,下面是一個(gè)更清晰的例子狐史。
var counter = {
count: 0,
inc: function () {
this.count++;
}
};
var func = counter.inc.bind(counter);
func();
上面代碼中,counter.inc方法被賦值給變量func说墨。這時(shí)必須用bind方法將inc內(nèi)部的this骏全,綁定到counter,否則就會(huì)出錯(cuò)