结合实例对instanceof详解「建议收藏」

结合实例对instanceof详解「建议收藏」其实我是先写此篇,再写【ES6基础知识】class的继承,但是发现总结完【ES6基础知识】class的继承,再来理解此篇文章就很明白了。 我觉得任何东西的记忆都得建立在理解之上,才能成为自己大脑里的东西。 1. instanceof描述 instanceof运算符用来判断一个构…

结合实例对instanceof详解"

温馨提示:写这篇文章发现发布后__proto__会变成proto

写此篇的原因:

  1. 碰见instanceof第一反应肯定是检测A是否是B的实例,但是不知道其中原理
  2. 受尽原型链的折磨

其实我是先写此篇,再写【ES6基础知识】class的继承,但是发现总结完【ES6基础知识】class的继承,再来理解此篇文章就很明白了。

我觉得任何东西的记忆都得建立在理解之上,才能成为自己大脑里的东西。

1. instanceof描述

instanceof运算符用来判断一个构造函数的prototype属性所指向的对象是否存在另外一个要检测对象的原型链上。

也就是obj instanceof Object 检测Object.prototype是否存在于参数obj的原型链上。

2. 原型链基础

  • Object.proto =>function () {}

  • Function.proto =>function () {}

  • Function.prototype =>function () {}

  • Object.prototype =>Object { }

  • Function.prototype.proto =>Object { }

  • Object.proto.proto =>Object { }

  • Object.proto.proto.proto =>null

3. 用法

1)基本用法:检测Object.prototype是否存在于参数obj的原型链上

Person的原型在p的原型链中

functionPerson(){};
var p = new Person();
console.log(p instanceof Person);//true

2)继承中判断实例是否属于它的父类

StudentPerson都在s的原型链中

function Person(){};
function Student(){};
var p =new Person();
Student.prototype=p;//继承原型
var s=new Student();
console.log(s instanceof Student);//true
console.log(s instanceof Person);//true

3)复杂用法

function Person() {}

由原型链基础得出以下结果

Object instanceof Object =>true

第一个Object的原型链:Object=>Object.__proto__ => Function.prototype=>Function.prototype.__proto__=>Object.prototype
第二个Object的原型:Object=> Object.prototype

Function instanceof Function =>true

第一个Function的原型链:Function=>Function.proto => Function.prototype 第二个Function的原型:Function=>Function.prototype

Function instanceof Object =>true

Function=>Function.__proto__=>Function.prototype=>Function.prototype.__proto__=>Object.prototype
Object => Object.prototype

Person instanceof Function =>true

Person=>Person.__proto__=>Function.prototype
Function=>Function.prototype

String instanceof String =>false

第一个String的原型链:String=>String.__proto__=>Function.prototype=>Function.prototype.__proto__=>Object.prototype
第二个String的原型链:String=>String.prototype

Boolean instanceof Boolean =>false

第一个Boolean的原型链:Boolean=>Boolean.__proto__=>Function.prototype=>Function.prototype.__proto__=>Object.prototype
第二个Boolean的原型链:Boolean=>Boolean.prototype

Person instanceof Person =>false

第一个Person的原型链:Person=>Person.__proto__=>Function.prototype=>Function.prototype.__proto__=>Object.prototype
第二个Person的原型链:Person=>Person.prototype

4. 模拟实现一个instanceof方法

function myInstanceof(left, right) {
  let proto = left.__proto__;
    let prototype = right.prototype;
    while(true){
        if(proto === null) return false
        if(proto === prototype) return true
        proto = proto.__proto__;
    }
}
console.log(myInstanceof(Object, Object))   //true
console.log(myinstanceof(Function, Function))  //true
console.log(myinstanceof(Boolean, Boolean))  //false
console.log(myinstanceof(Person, Person))   //false

5. prototype和proto的区别

__proto__是每个对象都有的一个属性,而prototype是函数才会有的属性!!!

prototype

  • 几乎所有的函数(除了一些内建函数如Function.prototype)都有一个名为prototype(原型)的属性 ,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以有特定类型的所有实例共享的属性和方法。

  • Object.prototype是所有函数的爹,当你声明一个函数的时候也就是相当于对Object的实例化,在【ES6基础知识】class的继承中不存在任何继承的特殊情况,可以体现。

class A {
}

A.__proto__ === Function.prototype // true
A.prototype.__proto__ === Object.prototype // true
console.log(new A())  //A {}

prototype是通过调用构造函数而创建的那个对象实例的原型对象

延伸到:

  • hasOwnProperty()判断指定属性是否为自有属性;in操作符对原型属性和自有属性都返回true。

proto

  • 凡是对象都会有一个属性那就是__proto_,可称为隐式原型,指向构造该对象的构造函数的原型,这也保证了实例能够访问在构造函数原型中定义的属性和方法。_

我的总结

  • 一般说__proto__是指向构造函数的原型,prototype是对象实例的原型对象。

  • 看到.prototype.proto就想到实例方法的继承,看到.proto就想到构造函数的继承

实例分析更好理解prototype和proto

function B(b){
	this.b = b;
}
var b = new B('hy');

B.prototype.__proto__指向的就是Object.prototype

Object.prototype是一个对象

b对象的__proto__属性指向它构造函数B的prototype属性,这就是区别。

那么什么是原型链呢?接着上面的讲,我们都知道对象都有一个toString方法。上述的实例化对象b也可以toString, 而实例化对象b本身并没有toString的方法,那他就会沿着它的__proto__向他的构造函数B的prototype对象去找,而这里也没有,那他就会继续沿着B.prototype.__proto__向上找。而B.prototype.__proto__指向的就是Object.prototype.

(我的理解这句话的意思是:通过沿着__proto__,再根据b对象的__proto__属性指向它构造函数B的prototype属性,最后面找到Object.prototype)

所以B.prototype.proto 跟 Object.prototype相等。

function B(){}
let b = new B();

console.log(b.constructor)  //function B(){}
console.log(B.constructor)  //function Function() { [native code] }

console.log(B.prototype)   //[object Object]
/* 要知道B.prototype是指B上面的原型对象,B是一个函数,它原型对象上有构造函数和原型__proto__ {constructor: ƒ} constructor: ƒ B() __proto__: Object */

console.log(Object.prototype)  // Object { }
/* {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …} constructor: ƒ Object() hasOwnProperty: ƒ hasOwnProperty() isPrototypeOf: ƒ isPrototypeOf() propertyIsEnumerable: ƒ propertyIsEnumerable() toLocaleString: ƒ toLocaleString() toString: ƒ toString() valueOf: ƒ valueOf() __defineGetter__: ƒ __defineGetter__() __defineSetter__: ƒ __defineSetter__() __lookupGetter__: ƒ __lookupGetter__() __lookupSetter__: ƒ __lookupSetter__() get __proto__: ƒ __proto__() set __proto__: ƒ __proto__() */

/* 我觉得:通过Function.prototype得到的结果,prototype不一定都是返回对象,如果有错大神指正下 */
console.log(Function.prototype)  //function () {[native code]}

/* Object.prototype是所有函数的爹,所以 b和B是Object的实例对象,B函数也是Function的实例对象 */

console.log(b instanceof Function) //false
console.log(b instanceof Object)//true

console.log(B instanceof Function)//true
console.log(B instanceof Object)//true

console.log(Object.prototype.isPrototypeOf(B))//true
console.log(B instanceOf Object) //true

console.log(B.__proto__)   // function () {[native code]}
根据函数也是对象,指向构造该对象的构造函数的原型,

也就是指向构造B的构造函数是function Function() { [native code] },
它的prototype是 function () {}

由此得出一直费解的
1.构造函数:function Function() { [native code] }
2.原型: function () {}
3.console.log(B instanceof Function)//true

Object.prototype 又是所有函数的爹,所以得出:
console.log(B instanceOf Object) //true
console.log(Object.prototype.isPrototypeOf(B))//true


console.log(b.__proto__)   //[object Object]
b的构造函数是B,B的原型是对象

因为b对象的__proto__属性指向它构造函数B的prototype属性,很容易理解



console.log(b instanceof Function) //false
console.log(b instanceof Object)//true

由b.__proto__ = B.prototype,根据原型链继续向上查找B.prototype.__proto__ ,而B.prototype.__proto__指向的就是Object.prototype,所以得出console.log(b instanceof Object)//true

因为console.log(Function.prototype)  //function () {},所以console.log(b instanceof Function) //false

总结:

console.log(b.constructor)  //function B(){}
console.log(B.constructor)  //function Function() { [native code] }

console.log(B.prototype)   //[object Object]
console.log(Object.prototype)  // Object { }

console.log(Function.prototype)  //function () {}
console.log(Function.__proto__)  //function () {}

1.几乎所有的函数(除了一些内建函数)都有一个名为prototype(原型)的属性;
2.Object.prototype是所有函数的爹;
3.对象都会有一个属性那就是__proto__

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/13905.html

(0)

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注