原型继承

当我们期望得到一个"类"继承自另外一个"类"的效果时,会用一下代码实现:

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);

你可能感兴趣的:(原型继承)