Detailed explanation of prototype, prototype chain, instanceof, isprototypeof

Mainly clarify these concepts:

  1. Inheritance (prototype, prototype chain, prototype, proto , new)
  2. The difference between instanceof and isprototypeof

1. Concept

1.1 The source of javascript inheritance

I can't always remember the principle and reason of JavaScript's prototype inheritance, and my mind is easy to get confused. View Ruan Yifeng article after he summarized as follows:

  • At the beginning, a scripting language is needed, and it does not need to be complicated.
  • Java was very popular at the time, and Java used object objects. So decided to use the object object.
  • Both c++ and java have new to create objects, and javascript also references new,
  • But to simplify new, the object of new in javascript is a constructor, that is, a function.
  • But new has a shortcoming that it cannot share data, so the prototype comes out, so that the private data is in the constructor, and the shared data is in the prototype.
function  dog(name){
  this.name = name
}

dog.prototype = {
  type:"animate"
}

var a = new dog('gou')
var b = new dog('mao')
dog.prototype.type = 'dongwu';

console.log(a.name); // gou
console.log(b.name); // mao
console.log(a.type); // dongwu
console.log(b.type); // dongwu

1.2 Prototype chain concept

I must put this picture (^_^)
JavaScript prototype chain

The following is the concept I understand: the original concept can be seen here

  1. The instance object has __proto__ attribute (point to the prototype object of the constructor)
  2. Function has prototype attribute
  3. The prototype of the function is the object type
  4. The __proto__ attribute points to the prototype object of the function, prototype is the prototype object of the function
  5. Object.__proto__ === Function.__proto__ === foo.__proto__ === Function.prototype

The prototype chain I understand:

  Everything in javascript is an object. Each instance object has a __proto__ attribute, which points to the instance object (prototype) of its constructor, and the instance object is an object, so it has the __proto__ attribute until it is null, which is The generation of the prototype chain.
  ps: Why use the __proto_ attribute, you can refer to the implementation of new at the bottom of this article. _

The concept of light is not good, and there are two chestnuts:

Function.prototype.a = 'Function'
Object.prototype.a = 'Object'
function foo(name){
    
    }
var a = new foo();
console.log(a.a) // Object

// 原型链从__proto__开始查找, 
// 步骤:foo.__proto__ ---> foo.prototype ---> Object.prototype
// 结果: Object, 根本未经历Function.prototype
function foo(){
    
    }
var a = new foo();
console.log(a.__proto__ === foo.prototype); // true, proto指向声明它的原型的prototype
console.log(foo.__proto__ === Function.prototype) // true, function声明变量的proto指向Function.prototype
console.log(Function.prototype.__proto__ === Object.prototype); // true, prototype也有proto,指向Object的prototype
console.log(Object.prototype.__proto__ === null); //true, Object的prototype的proto指向null

ps : It's better to go to authoritative websites to see some original concepts, this will be better.


3.instanceof

A instanceof B
Statement 1: Whether the prototype object of the B constructor is on the prototype chain of A
Statement 2: Is the A object an instance of the B object
Statement 3: Is the B object the parent object of the A object
I think Statement 2 is the most appropriate

Fake code:

function instanceof(left,right){
    
    
    while(true){
    
    
        if(left.__proto__ === null){
    
    
            return false;
        }

        if(left.__proto__ === right.prototype){
    
    
            return true;
        }

        left = left.__proto__;
    }
}

Error-prone little chestnuts:

var simpleStr = "This is a simple string"; 
var myString  = new String();
var newStr    = new String("String created with constructor");

simpleStr instanceof String; // 返回 false, 检查原型链会找到 undefined
myString  instanceof String; // 返回 true
newStr    instanceof String; // 返回 true
myString  instanceof Object; // 返回 true

Object.create(null) instanceof Object // false, 创建了一个原型为null的空对象,检查原型链会找到 undefined

Error-prone little chestnut 2: the difference with isprototypeof (the answer is all true)

var fn = function(){
    this.nick = 'nick'
    this.age = '18'
}

fn.prototype.getNick = function(){
    console.log(this.nick)
}

fn.hello = function(){
    console.log('hello')
}

fn.getAge = function(){
    console.log(this.hello())
    return '1'
}

var sub = function(){

}

sub.prototype = Object.create(fn.prototype)
sub.prototype.constructor = sub;

var sb = new sub();

console.log(sb instanceof fn)
console.log(fn.prototype.isPrototypeOf(sb))


var c = Object.create(fn.prototype)

console.log(c instanceof fn)
console.log(fn.prototype.isPrototypeOf(c))


var obj = {
    a:'a'
}

var t = Object.create(obj)

console.log(t instanceof Object)
console.log(Object.prototype.isPrototypeOf(t))

4. isprototypeof

A.isPrototypeOf(B):
Whether the B object is on the prototype chain of A

var o={
    
    };
function Person(){
    
    };
var p1 =new Person();//继承自原来的原型,但是现在已经无法访问
Person.prototype=o;
var p2 =new Person();//继承自o
console.log(o.isPrototypeOf(p1));//false o不是p1的原型
console.log(o.isPrototypeOf(p2));//true o是p2的原型

// 这个栗子来源于网上,我稍微修改了一下。我认为这个栗子并不好,  
// 因为实际使用一般是o.prototype.isPrototypeOf(p2),而非o.isPrototypeOf(p2)

5. The difference between instanceof and isprototypeof

I think that the difference between the parameters is
not the difference between the parameters, but the latter is more comprehensive (can be tested on the constructor)
is the difference between the parameters
object instanceof constrouctor
prototypeObject.isPrototypeOf(Object)

6. new

Quoted from: Address

function myNew(){
    
    
	var constructor = [].shift.call(arguments); //注意是shift,不是slice
	var obj = new Object();
	obj.__proto__ = constructor.prototype;
	constructor.apply(obj,arugments)
	return obj;
}

Guess you like

Origin blog.csdn.net/a519991963/article/details/95505746