如何理解JavaScript原型链和instanceof运算符之间的暧昧关系,相信很多没有经验的人对此无能为力。因此,本文总结了出现问题的原因和解决方法,希望大家可以通过这篇文章来解决这个问题。
回到两个月前,我简单了解了原型链、原型和__proto__之间的混乱关系,也简单了解了typeof和instanceof的运算符。但是,无论如何,尝试以下两个问题:
控制台日志(函数的函数实例);
控制台日志(字符串的字符串实例);
如果得不到准确答案,跟着楼主学点新东西。
温故
我们经常用typeof运算符来判断一个变量的类型,确实很好用,可以判断number、boolean、string,但是对于object的判断能力一般,比如Array、null的判断结果都是object,一些新对象的结果,比如new String()和new Number(),都是object,这样就有问题了,无法更详细的判断对象实例。此时,需要instanceof。instanceof是判断一个对象是否是构造函数实例的运算符。这样一来,从new来的变量是数字、字符串还是别的什么就可以进一步判断了。看似很简单,实则不然。以上两个问题只是一个小测试。让我们先把它们放在一边,然后回顾原型链。
JavaScript中的一切都是一个对象,所有对象的属性值都是__proto__(即prototype),这可能是某些特技浏览器不支持的。暂时一个对象的这个属性的值是该对象的构造函数的原型值,这意味着对于某一类型的对象,不需要重复定义某一方法。例如,对于对象[1,2,3],它显然是一个数组对象。它有pop、push等方法,但不代表它有这些方法,而是它的构造函数Array函数,这个对象的__proto__的值就是Array函数的原型值。如果没有pop方法,它将从它的__proto__中寻找它,这被称为原型链。而链的末端是object,因为所有的Objects都是由Object构造的,Object.prototype.__proto__指定它指向null。
文字描述总是苍白无力的,举个简单的例子:
var fun=function(){ 0
this . a=1;
};
fun . prototype . b=2;
var obj=new fun();
物体a;//1
obj.b//2
网上盗窃的例子和图片,仔细看就能看清楚。
知新
让我们看看操作符的实例。
instanceof的一般用法是判断a是否属于b类型:
console . log(TrueInstanceOpoolean);//false console . log(new number(1)instance number);//trueinstanceof还可以确定父类型:
functionChild神父(){ } function child(){ } child . prototype=new神父();vara=NewChild();console . log(ainstanceofChild);//true console . log(ainstanceofFather);//trueChild构造函数继承自父,实例A无疑是由Child构造的,但为什么也是父的实例呢?实际上,instanceof运算符的内核可以简单地使用以下代码。
描述:
function check(a, b) { while(a.__proto__) { if(a.__proto__ === b.prototype) return true; a = a.__proto__; } return false; } function Foo() {} console.log(Object instanceof Object === check(Object, Object)); // true console.log(Function instanceof Function === check(Function, Function)); // true console.log(Number instanceof Number === check(Number, Number)); // true console.log(String instanceof String === check(String, String)); // true console.log(Function instanceof Object === check(Function, Object)); // true console.log(Foo instanceof Function === check(Foo, Function)); // true console.log(Foo instanceof Foo === check(Foo, Foo)); // true
简单地说,a如果是b的实例,那么a肯定能使用b的prototype中定义的方法和属性,那么用代码表示就是a的原型链中有b.prototype取值相同的对象,于是顺着a的原型链一层层找就行了。
另外值得注意的是,String Number Boolean 以及Function等都是函数,而函数则是统一由Function构造而来的,so它们和任何单纯的函数一样,能用Function上的原型属性:
Function.prototype.a = 10; console.log(String.a); // 10
***来简单讲讲最开始的两道题吧。
// 为了方便表述,首先区分左侧表达式和右侧表达式 FunctionL = Function, FunctionR = Function; // 下面根据规范逐步推演 O = FunctionR.prototype = Function.prototype L = FunctionL.__proto__ = Function.prototype // ***次判断 O == L // 返回 true
// 为了方便表述,首先区分左侧表达式和右侧表达式 StringL = String, StringR = String; // 下面根据规范逐步推演 O = StringR.prototype = String.prototype L = StringL.__proto__ = Function.prototype // ***次判断 O != L // 循环再次查找 L 是否还有 __proto__ L = String.prototype.__proto__ = Object.prototype // 第二次判断 O != L // 再次循环查找 L 是否还有 __proto__ L = String.prototype.__proto__ = null // 第三次判断 L == null // 返回 false
看完上述内容,你们掌握如何理解JavaScript原型链和instanceof运算符的暧昧关系的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注行业资讯频道,感谢各位的阅读!
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/56685.html