Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

自己动手理解js原型和原型链继承方式 #17

Open
zp1112 opened this issue May 22, 2018 · 0 comments
Open

自己动手理解js原型和原型链继承方式 #17

zp1112 opened this issue May 22, 2018 · 0 comments

Comments

@zp1112
Copy link
Owner

zp1112 commented May 22, 2018

什么是原型

不想写~~~自己搜。。

实现一个new函数

判断一个对象是否是一个类的实例可以使用a instanceof b,instanceof 运算符用来检测 constructor.prototype 是否存在于参数 object 的原型链上,即只要a顺着__proto__能找到某个__proto__等于b的prototype的都能返回true

实现一个instanceof

function instanceof(A, B) {
  const O = B.prototype;
  let A = A.__proto__ ;
  while(true) {
    if (A === null) return false; // 直到找到null
    if (A === O) return true;
    A = A.__proto__; // 顺着往上找
  }
}

根据上述特性,可以实现一个new函数,模拟new语法

function mynew (Class, options) {
  const obj = {};
  Class.call(obj, options);
  obj.__proto__ = Class.prototype;
  return obj;
}
function Person(name) {
  this.name = name;
}
Person.prototype.sayhi = function(){console.log(this.name)}
const p1 = mynew(Person, 'candy');
p1.sayhi() // candy

实现继承

继承的原理在于子类为了继承父类的原型方法,需要将子类的prototype 合并父类的prototype 再新增自己的一些原型方法,同时,由于Person1.prototype = Person.prototype的行为会导致constructor丢失,所以需要手动添加,指向构造函数本身,为了继承父类的属性,需要在子类的构造函数即子类函数中,调用一遍父类的构造函数,从把父类的属性挂到子类的实例对象上,如果子类和父类的属性有重复,则使用子类的属性覆盖。因此可以得到如下继承方式。

function Person1(name) {
  this.super(name)
  // Person.call(this, name); 或者使用call执行
}
// Object.create将Person1.prototype.__proto__指向Person.prototype,并添加constructor为Person1
Person1.prototype = Object.create(Person.prototype, {
  constructor: {
    value: Person1,
    enumerable: false,
    writable: true,
    configurable: true
  }
})
// prototype上添加super方法,用于执行一次Person
Person1.prototype.super = Person;
let person1 = new Person1('candy');
console.log(person1.name); // candy

总结

原型链继承的精髓在于,让原型对象(子类原型对象)等于另一个类型(父类)的实例

每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数想指针(constructor),而实例对象都包含一个指向原型对象的内部指针(proto)。如果让原型对象等于另一个类型的实例,此时的原型对象将包含一个指向另一个原型的指针(proto),另一个原型也包含着一个指向另一个构造函数的指针(constructor)。假如另一个原型又是另一个类型的实例……这就构成了实例与原型的链条。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant