Git Product home page Git Product logo

Comments (1)

SWbeginner avatar SWbeginner commented on June 12, 2024

原型链

想要理解原型链,先要了解什么是原型

一、原型模式

我们创建的每个函数都有一个==prototype==(原型)属性,prototype属性指向原型对象。通过该函数创建的实例对象会共享原型对象上的所有属性和方法。

function Person(){
    
}

Person.prototype.name = 'test';
Person.prototype.age = 25;
Person.prototype.sayName = function(){
    console.log(this.name);
}

const person1 = new Person();
person1.sayName(); //'test'

const person2 = new Person();
person2.sayName(); //'test'

console.log(person1.sayName === person2.sayName); //true

二、原型对象

  1. 理解原型对象

只要创建了一个函数,就会为该函数生成一个==prototype==属性(指向函数的原型对象)。默认情况下,原型对象会自动获得一个==constructor==属性(构造函数属性),这个属性包含一个指向prototype属性所在函数的指针。当调用该函数创建一个实例后,该实例内部将包含一个指针[[Prototype]](内部属性),指向构造函数的原型对象。虽然在脚本中没有标准的方式访问[[Prototype]],但Firefox、Safari和Chrome在每个对象上都支持一个属性__proto__。而在其他实现中,这个属性对脚本则是完全不可见的。

image

虽然在所有实现中都无法访问到[[Prototype]],但可以通过==isPrototypeOf==方法来确定对象之间是否存在这种关系。如果[[Prototype]]指向调用isPrototypeOf()方法的对象(Person.prototype),那么这个方法就返回true。

Person.prototype.isPrototypeOf(person1); //true
Person.prototype.isPrototypeOf(person2); //true

==Object.getPrototypeOf==方法可以返回[[Prototype]]的值。例如:

Object.getPrototypeOf(person1) === Person.prototype // true
Object.getPrototypeOf(person1).name // "test"

每当读取对象的某个属性时,都会首先从对象实例本身开始搜索,如果没有则继续搜索原型对象中的属性。虽然可以通过对象实例访问保存在原型中的值,但却不能通过对象实例重写原型中的值。

person1.name = "Greg";
console.log(person1.name); // "Greg" 来自实例本身
console.log(person2.name); // "test" 来自原型对象

==hasOwnProperty==方法可以检测一个属性是存在于实例中,还是存在于原型中(从Object继承来的),只在给定属性存在于对象实例中时,才会返回true。

person1.hasOwnProperty("name"); //true
person2.hasOwnProperty("name"); //false

delete person1.name;

person1.hasOwnProperty("name"); //false
  1. 原型与in操作符

单独使用in操作符时,无论属性存在于实例中还是原型中,只要能访问到给定属性都返回true。

person1.hasOwnProperty('name'); //false
'name' in person1; //true

person2.hasOwnProperty('name'); //false
'name' in person2; //true

person1.name = 'ohyes';
person1.name; // 'ohyes'
person1.hasOwnProperty('name'); //true
'name' in person1; //true
//通过使用hasOwnProperty方法和in操作符可以确定属性是存在于实例中还是原型中

function hasPrototypeProperty(obj,name){
    return !obj.hasOwnProperty(name) && name in obj;
}

//属性存在于实例中,返回false;存在于原型中返回true

for - in循环,能够返回对象中所有可枚举的属性,无论存在于实例中还是原型中。屏蔽了原型中不可枚举属性的实例属性也可以在for-in循环中返回。但是在IE8以及更早版本有bug,即屏蔽不可枚举属性的实例属性不会出现在for-in 循环中。

要取得对象上所有可枚举的实例属性,可以使用Object.keys()方法。

Object.keys(Person.prototype); // ["name", "age", "sayName"]
Object.keys(person1); // ["name"]

如果想要得到所有的实例属性,无论是否可枚举,可以使用Object.getOwnPropertyNames()方法

Object.getOwnPropertyNames(Person.prototype); // ["constructor", "name", "age", "sayName"]
  1. 原型对象的问题

原型中所有属性是被很多实例共享的。对于包含引用类型值的属性的原型对象,会有特别的问题。

//在实例中修改了原型上的引用类型的属性,会在所有实例上反映出来

Person.prototype.friends = ['one', 'two'];
person1.friends.push('three');

person1.friends; // ["one", "two", "three"]
person2.friends; // ["one", "two", "three"]
person2.friends === person1.friends; // true

三、原型链

原型链是实现继承的主要方法。其基本**是利用原型让一个引用类型继承另一个引用类型的属性和方法。每个构造函数都有一个prototype属性,指向原型对象。原型对象都包含一个指向构造函数的指针(constructor)。把构造函数的prototype属性修改成另一个构造函数的实例,此时原型对象就将包含指向另一个原型的指针。假如另一个原型又是另一个类型的实例,那么上述关系依然成立,如此层层递进,就构成了实例与原型的链条。这就是原型链的概念。

//修改构造函数的prototype属性指向另一个构造函数的实例,实现继承
function SuperType(){
    this.property = true;    
}

SuperType.prototype.getSuperValue = function(){
    return this.property;
}

function SubType(){
    this.subproperty = false;
}

SubType.prototype = new SuperType();

SubType.prototype.getSubValue = function(){
    return this.subproperty;
}

let instance = new SubType();
console.log(instance.getSuperValue()); //true

from my-blog.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.