大家好,我是考100分的小小码 ,祝大家学习进步,加薪顺利呀。今天说一说结合实例对instanceof详解「建议收藏」,希望您对编程的造诣更进一步.
温馨提示:写这篇文章发现发布后__proto__
会变成proto
写此篇的原因:
- 碰见instanceof第一反应肯定是检测A是否是B的实例,但是不知道其中原理
- 受尽原型链的折磨
其实我是先写此篇,再写【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)继承中判断实例是否属于它的父类
Student和Person都在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