Home > Web Front-end > JS Tutorial > Understanding common patterns and prototype chains

Understanding common patterns and prototype chains

PHP中文网
Release: 2017-06-20 09:37:30
Original
1777 people have browsed it

Content:

  • Several modes of creating objects and the process of creation

  • Understanding of prototype chain prototype, and prototype Relationship with __proto__ ([[Prototype]])

  • Several implementations of inheritance


1. Understanding common patterns and prototype chains

a.Constructor creation

function Test() {// 
}
Copy after login

Process

  • Create function A prototype attribute will be created for Test by default. Test.prototype contains a pointer pointing to Object.prototype

  • prototype will default to There is a constructor, and Test.prototype.constructor = Test

  • Other methods in prototype are inherited from Object


Example
// 调用构造函数创建实例
var instance = new Test()
Copy after login

The instance here contains a pointer to the prototype of the constructor, (the pointer here is called in chrome __proto__, also equal to [[Prototype]])


##Example
b.Prototype pattern

From the above we can know that the prototype properties created by default only have constructor and properties inherited from Object. The prototype mode is to add properties and methods to the prototype

Test.prototype.getName = ()=> {
    alert('name')
}
Copy after login

At this time, the instance instance has the getName method, because The pointer of the instance is pointing to Test.prototype

instance.__proto__ === Test.prototype
Copy after login

As shown in the figure below

##897RVF]E5@IX$)`IVJ3BOSY.png
Here we can learn that the instance instance and the constructor are related through the prototype
prototype

. c. Combination mode

We use this mode the most. It is actually another way of writing the prototype mode, but there is a slight difference.

function Test() {}

Test.prototype = {
    getName() {
        alert('name')
    }
}
Copy after login

We often use it so directly Rewrite the prototype method. From the above, we know that the prototype will have the constructor attribute pointing to the constructor itself by default. So what happens after rewriting?

Test.prototype.constructor === Object 
// 而并不等于Test了// 因为重写以后相当于利用字面量方式创建一个实例对象,这个实例的构造函数是指向Object本身的
Copy after login

Of course we can also manually assign the constructor

Test.prototype = {
    constructor: Test,
    getName() {
        alert('name')
    }
}
Copy after login

Then there will be questions again

constructor

What is the meaning of it? I think the meaning of constructor is just to identify the constructor to which the prototype belongs. When a certain attribute needs to be obtained, it will be searched from the instance first. If not, it will be searched according to the prototype pointed to by the pointer, and then upwards until the instance pointer

__proto__

points to null. Stop searching when, for example: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="hljs elm">// 1 读取nameinstance.name // 2 instance.__proto__ === Test.prototypeTest.prototype.name // 3 Test.prototype.__proto__ === Object.prototypeObject.prototype.name // 4Object.prototype.__proto__ === null</pre><div class="contentsignin">Copy after login</div></div>When this attribute is found, it will be returned directly without continuing to search. Even if the attribute value is null, if we want to continue searching, we can pass

delete

operator to achieve. From here we can naturally think that

Array, Date, Function, String

are all a constructor, and their prototype pointers point to Object.prototype, They are just like the Test I defined here, but they are just native.d. Several useful methods

  • Object.getPrototypeOf()

    Get the prototype pointed to by the pointer of an instance<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="hljs elm">Object.getPrototypeOf(instance) === Test.prototype</pre><div class="contentsignin">Copy after login</div></div>

  • hasOwnProperty

    Determine whether a property exists in the instance or in In the prototype, as shown in the figure:

    NY~N}CNR`}8W%4QA$M8LFE4.png
  • in

    Operator, regardless of whether the property is enumerable or not <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="hljs smali">&amp;#39;name&amp;#39; in instance // true &amp;#39;getName&amp;#39; in instance // true</pre><div class="contentsignin">Copy after login</div></div> Returns true whether the property is in an instance or in a prototype, so when we need to determine a Are there two ways to do it: the attribute exists in the instance or in the prototype?

    // 一种就是使用hasOwnProperty判断在实例中
    // 另一种判断在原型中
    instance.hasOwnProperty(&#39;getName&#39;) === false && &#39;getName&#39; in instance === true
    Copy after login

  • for... in

    The operator is the same, but only enumerable ones will be listed The bug of the IE8 version is that no matter whether the attribute is enumerable or not, it will be listed

    ##D(%S__GN8404{H9X6PW$DVK.png


    name是在实例中定义的,getName是在原型中定义的

  • Object.keys()则不一样,它返回一个对象上所有可枚举的属性,仅仅是该实例中的

    Object.keys(instance)// ["name"]
    Copy after login

e.总结
以上讨论了构造函数,原型和实例的关系:

  • 每个构造函数都有原型对象

  • 每个原型对象都有一个constructor指针指向构造函数

  • 每个实例都有一个__proto__指针指向原型

2.继承

其实是一个道理,这里我们不难想到,将Child.prototype指向parent实例,就是利用原型实现的继承,而为了每个实例都拥有各自的colors和name,也就是基础属性,在Child的构造函数中call调用了Parent的构造函数,相当于每次实例化的时候都初始化一遍colors和name,而不是所有实例共享原型链中的colors和name。

继承的实质是利用构造函数的原型 = 某个构造函数的实例,以此来形成原型链。例如

// 定义父类function Parent() {}Parent.prototype.getName = ()=> {
    console.log(&#39;parent&#39;)
}// 实例化父类let parent = new Parent()// 定义子类function Child() {}
Child.prototype = parent 
// 实例化子类let child = new Child()

child.getName() // parent// 此时
child.constructor === parent.constructor === Parent
Copy after login

a.最经典的继承模式

function Parent(name) {this.name = namethis.colors = [&#39;red&#39;]
}
Parent.prototype.getName = function() {console.log(this.name)
}// 实例化父类let parent = new Parent()function Child(age, name) {
    Parent.call(this, name)this.age = age
}
Child.prototype = parent 
// 实例化子类let child = new Child(1, &#39;aaa&#39;)
child.getName() // parent
Copy after login

这里会让我想到ES6中的class继承

class Parent {
    constructor(name) {this.name = namethis.colors = [&#39;red&#39;]
    }
    getName() {
        console.log(this.name)
    }
}class Child extends Parent {
    constructor(age, name) {super(name)
    }
}

let child = new Child(1, &#39;aaa&#39;)
child.getName() // parent
Copy after login

The above is the detailed content of Understanding common patterns and prototype chains. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template