Home > Web Front-end > JS Tutorial > body text

Introduction to JavaScript prototypes and prototype chain methods (code examples)

不言
Release: 2019-01-10 10:59:44
forward
2726 people have browsed it

This article brings you an introduction to JavaScript prototypes and prototype chain methods (code examples). It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.

1. Question

How to accurately determine whether a variable is an array

Write an example of prototype chain inheritance

Other ways of inheritance implementation

es6 What is the underlying principle of inheritance

Describe the process of new an object

How to use the prototype chain in zepto and other source codes

2. Knowledge points

2.1 Constructor

Features: Starting with a capital letter

function Foo(name,age){
    //var obj = {}
    //this = {}
    this.name = name;
    this.age = age;
    this.class = 'class1'
    // return this
}

var f1 = new Foo('liming',19);
Copy after login

Extension

var o = {} is the syntactic sugar of var o = new Object()

var a = [] is the syntactic sugar of var a = new Array()

function Foo(){} is equivalent to var Foo = new Function(){}

2.2 Prototype rules

Five rules:

1. All reference types (objects, arrays, functions) All have object characteristics, that is, attributes can be freely extended

2. All reference types (objects, arrays, functions) have a __proto__ (implicit prototype) attribute, which is an ordinary object

3. All functions have prototype (explicit prototype) attributes and are also ordinary objects

4. All reference types (objects, arrays, functions) __proto__ value points to the prototype of its constructor

5. When trying to get the attributes of an object, if the variable itself does not have this attribute, it will go to its __proto__ to find it

for (var key in object) {
    //高级浏览器中已经屏蔽了来自原型的属性
    //建议加上判断保证程序的健壮性
    if (object.hasOwnProperty(key)) {
        console.log(object[key]);
    }
}
Copy after login

2.3 Prototype chain

obj.__ proto . proto . proto __ ...

Object.prototype === null

instanceof is used for judgment Which constructor does the reference type belong to

obj instanceob Foo

Actual meaning: Determine whether Foo.prototype is on the prototype chain of obj

3. Question answer

3.1 How to accurately determine whether a variable is an array

arr instanceof Array

##3.2 Write an example of prototype chain inheritance

Encapsulate dom query

function Elem(id){
    this.elem = document.getElementById(id);
};

Elem.prototype.html = function(val){
    var elem = this.elem;
    if (val) {
        elem.innerHTML = val;
        return this;
    }else{
        return elem.innerHTML;
    }
}

Elem.prototype.on = function(type,fun){
    var elem = this.elem;
    elem.addEventListener(type,fun);
    return this;
}

var p1 = new Elem('id1');
p1.html("test").on('click',function(){
    console.log('点击');
})
Copy after login

3.3 Other ways of inheritance implementation

3.3.1 Prototypal inheritance

        var obj = {
            0:'a',
            1:'b',
            arr:[1]
        }
        
        function Foo(arr2){
            this.arr2 = [1]
        }

        Foo.prototype = obj;

        var foo1 = new Foo();
        var foo2 = new Foo();

        foo1.arr.push(2);
        foo1.arr2.push(2);

        console.log(foo2.arr);  //[1,2]
        console.log(foo2.arr2); //[1]
Copy after login
Advantages: Simple implementation

Disadvantages:

1. Unable to pass parameters to the parent class constructor

2. When new two objects are used at the same time, when a reference type attribute in the prototype of one object is changed, the attribute of the other object will also be modified. Because the reference properties from the prototype object are shared by all instances.

3.3.2 Structural inheritance

        function Super(b){
            this.b = b;
            this.fun = function(){}
        }
        function Foo(a,b){
            this.a = a;
            Super.call(this,b);
        }

        var foo1 = new Foo(1,2);
        console.log(foo1.b);
Copy after login

Advantages: You can pass parameters to the parent class, and the subclass will not share the reference attributes of the parent class

Disadvantages: Function reuse cannot be achieved , each subclass has new fun, too many will affect performance, and the prototype object of the parent class cannot be inherited.

3.3.3 Combined inheritance

function Super(){
    // 只在此处声明基本属性和引用属性
    this.val = 1;
    this.arr = [1];
}
//  在此处声明函数
Super.prototype.fun1 = function(){};
Super.prototype.fun2 = function(){};
//Super.prototype.fun3...
function Sub(){
    Super.call(this);   // 核心
    // ...
}
Sub.prototype = new Super();
Copy after login

Advantages: There is no problem of sharing reference attributes, parameters can be passed, and functions can be reused

Disadvantages: The attributes of the parent class will be instantiated Transformed twice, the real instance parent class cannot be obtained (it is impossible to distinguish whether the instance is created by the parent class or not)

Optimization:

         function Super(b){
            this.b = b;
            this.fun = function(){}
        }

        Super.prototype.c = function(){console.log(1111)}

        function Foo(a,b){
            this.a = a;
            Super.call(this,b);
        }


        Foo.prototype = Super.prototype;
        //修复构造函数:
        var foo1 = new Foo(1,2);
Copy after login
Disadvantages: It is impossible to distinguish whether the instance is created by the parent class or not. Subclass creation

3.3.4 Parasitic combination inheritance

         function Super(b){
            this.b = b;
        }

        Super.prototype.c = function(){console.log(1111)}

        function Foo(a,b){
            this.a = a;
            Super.call(this,b);
        }

        var f = new Function();
        f.prototype = Super.prototype;
        Foo.prototype = new f();
        //等同于 Foo.prototype = Object.create(Super.prototype);
        
        var foo1 = new Foo(1,2);
Copy after login

Parasitize the prototype of the parent class, that is, wrap it into a prototype of an empty object, and then instantiate this object as a child Class peototype.

Disadvantages: It is impossible to distinguish whether an instance is created by a parent class or a subclass.

You can add the following code:

Foo.prototype.constructor = Foo
Copy after login
This solution cannot be used for the above combined optimization method , because the subclass and parent class refer to the same prototype object, modifications will be modified at the same time.

Summary:

Inheritance is mainly to realize the reuse of parent class methods and attributes by subclasses.

Reference properties from the prototype object are shared by all instances, so we want to avoid inheriting properties from the prototype.

You can inherit the attributes and methods of the parent class constructor through the call function in the constructor, but the instance instantiated in this way will store the parent class methods multiple times, which affects performance.

Through combined inheritance, we use call inheritance properties and the prototype inheritance method to solve the above two problems, but the object instantiated in this way will store two copies of the properties in the parent class constructor.

Constructing a new object using the prototype of the parent class as the prototype of the subclass solves the problem of multiple storage, so the final parasitic combination inheritance is the best inheritance method. Its disadvantage is that it is more troublesome to write. .

3.3.6 Inheritance implementation in node source code

function inherits(ctor, superCtor) {
  ctor.super_ = superCtor;
  ctor.prototype = Object.create(superCtor.prototype, {
    constructor: {
      value: ctor,
      enumerable: false,
      writable: true,
      configurable: true
    }
  });
}; 

function Stream(){
    //...
}

function OutgoingMessage() {
  Stream.call(this);
  //...
}

inherits(OutgoingMessage, Stream);

OutgoingMessage.prototype.setTimeout = ...
Copy after login

The above is an example of parasitic combination inheritance.

1. Inherit the properties in the Stream constructor by calling in the OutgoingMessage constructor.

2. Call the inherits method to inherit the properties in the Stream prototype.

3. Function that extends OutgoingMessage’s own prototype.

The Object.create method is used in the inherits method. The function of this method is to create a new object through the specified prototype object and properties.

ctor.prototype=Object.create(superCtor.prototype,{.....});
Copy after login
This method actually does the work of our parasitic combination inheritance above

var f = new Function();
f.prototype =superCtor.prototype;
return new f();
Copy after login
The following parameters are to add attributes to the prototype object, optional attributes (not required), that is, put Serves itself as the constructor of a newly created object.

value: 表示constructor 的属性值;
writable: 表示constructor 的属性值是否可写;[默认为: false]
enumerable: 表示属性constructor 是否可以被枚举;[默认为: false]
configurable: 表示属性constructor 是否可以被配置,例如 对obj.a做 delete操作是否允许;[默认为: false]
Copy after login
3.4 How to implement es6 inheritance

Refer to my article: https://segmentfault.com/a/11...

3.5 描述new一个对象的过程

  1. 创建一个对象

  2. {}._proto_ = 构造函数.prototype

  3. this指向这个对象

  4. 执行代码即对this赋值

  5. 返回this

3.6 zepto及其他源码中如何使用原型链

var Zepto = (function(){

    var $,zepto = {}
    
    // ...省略N行代码...
    
    $ = function(selector, context){
        return zepto.init(selector, context)
    }

    zepto.init = function(selector, context) {
        var dom
        
        // 针对参数情况,分别对dom赋值
        
        // 最终调用 zepto.Z 返回的数据
        return zepto.Z(dom, selector)
    }    

   fnction Z(dom, selector) {
      var i, len = dom ? dom.length : 0
     for (i = 0; i < len; i++) this[i] = dom[i]
      this.length = len
      this.selector = selector || ''
    }

   zepto.Z = function(dom, selector) {
     return new Z(dom, selector)
   }
  
    $.fn = {
        // 里面有若干个工具函数
    }
      
  
    zepto.Z.prototype = Z.prototype = $.fn
  
    
    // ...省略N行代码...
    
    return $
})()

window.Zepto = Zepto
window.$ === undefined && (window.$ = Zepto)
Copy after login

The above is the detailed content of Introduction to JavaScript prototypes and prototype chain methods (code examples). For more information, please follow other related articles on the PHP Chinese website!

source:segmentfault.com
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
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template