结合实例对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)

相关推荐

  • 阿里巴巴mysql面试_MySQL面试

    阿里巴巴mysql面试_MySQL面试迎面走来了一个风尘仆仆的身穿格子衫的男子,手里拿着一个MacBook Pro,看着那稀少的发量,和那从容淡定的眼神。 我心里一颤,我去,这是架构师,架构师来面我技术面,我心里顿时不淡定了,表面很稳实则心里慌得一批。 果然,他手里拿着我的简历,快速的扫了一下,然后用眼角余光看了一…

    2023-05-23
    136
  • sql递归查询父子节点「终于解决」

    sql递归查询父子节点「终于解决」一、表结构 二、递归查询当前节点的所有父节点 select * from test start with id = 3 connect by prior pid = id 三、递归查询当前节点的所有…

    2023-03-05
    160
  • Python中的数组操作详解

    Python中的数组操作详解在Python中,数组可以说是一个非常常用的数据结构之一了。它允许你使用单个变量来存储多个元素,甚至是不同类型的元素。在本篇文章中,我们将对Python中的数组操作做详细的阐述,包括数组的创建、读取、更新、删除等方面。

    2024-08-22
    30
  • Python中strfind方法的用法

    Python中strfind方法的用法strfind方法是Python中字符串类型的一个内置方法,在字符串中搜索指定的子字符串,并返回该子字符串在原字符串中第一次出现的索引位置。如果没有找到子字符串,则返回-1。

    2024-01-27
    100
  • [MySQL]MySQL8.0的一些注意事项以及解决方案[通俗易懂]

    [MySQL]MySQL8.0的一些注意事项以及解决方案[通俗易懂]MySQL8.0 注意事项以及解决方案 1. MySQL8.0 修改大小写敏感配置 天坑MySQL8.0! 在安装后, 便无法通过修改配置文件,重启服务,或者执行sql来更改数据库配置, 要想配置的话

    2023-05-10
    145
  • 一文详解GaussDB(DWS) 的并发管控和内存管控[亲测有效]

    一文详解GaussDB(DWS) 的并发管控和内存管控[亲测有效]摘要:DWS的负载管理分为两层,第一层为cn的全局并发控制,第二层为资源池级别的并发控制。 本文分享自华为云社区《GaussDB(DWS) 并发管控&内存管控》,作者: fighttingma

    2023-06-16
    151
  • SQL 入门教程:排序(ORDER BY)数据「终于解决」

    SQL 入门教程:排序(ORDER BY)数据「终于解决」目录汇总:SQL 入门教程:面向萌新小白的零基础入门教程 下面的 SQL 语句返回某个数据库表的单个列。但请看其输出,并没有特定的顺序。 输入▼ SELECT prod_name FROM Produ

    2023-04-19
    158
  • SQL基础随记 (Tobe Continued) – G「终于解决」

    SQL基础随记 (Tobe Continued) – G「终于解决」SQL基础随记 (Tobe Continued) 其实这里的随记,要是好久不接触突然被问的话有时还真的一时答不上,自己写一遍胜过盲扫。当然,也有些常读常新的地方会记录下来。 对SQL语言进行划分 DD

    2023-03-15
    159

发表回复

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