当我们期望得到一个"类"继承自另外一个"类"的效果时,会用一下代码实现:
var A = function(){};
A.prototype = {name:"seven"};
var B = function(){}
B.prototype = new A();
var b = new B();
console.log(b.name); //seven
分析下这段代码执行的时候,引擎做了什么事情:
1.首先,尝试遍历对象b中的所有属性,但没有找到name这个属性。
2.查找name属性的请求被委托给对象b的构造器的原型,它被b.proto记录着并且指向B.prototype,而B.prototype被设置为一个通过new A()创建出来的对象。
3.在该对象中依然没找到name属性,于是请求被继续委托给这个对象构造器的原型A.prototype。
4.在A.prototype中找到了name属性,并返回它的值。
ECMAScript6通过Class创建对象,但背后的原理仍是通过原型机制来创建对象。
class Animal{
constructor(name){
this.name = name;
}
getName(){
return this.name;
}
}
class Dog extends Animal{
constructor(name){
super(name);
}
speak(){
return "woof"
}
}
var dog = new Dog("assassin");
console.log(dog.getName() +' says '+ dog.speak());
输出为:assassin says woof.
一个简化版的Function.prototype.bind实现
Function.prototype.bind = function(){
var self = this, //保存原函数
context = [].shift.call(arguments), //需要绑定的this上下文
args = [].slice.call(arguments); //剩余的参数转化为数组
return function(){
return self.apply(context,[].concat.call(args,[].slice.call(arguments)));
//执行新的函数的时候,会把之前传入的context当做新函数体内的this
//并且组合两次分别传入的参数,作为新函数的参数
}
};
var obj = {
name:"seven"
};
var func = function(a,b,c,d){
alert(this.name); //seven
alert([a,b,c,d]); //[1,2,3,4]
}.bind(obj,1,2);
func(3,4);
网友评论