在JavaScript 中Object和Function 有什么关系?前面说过JavaScript的终点都是一个Object。但是似乎理解有不理解,就是像是说linux中的所有程序都是文件一样。现在不先阐述这个理论,毕竟阐述理论说实话不是我擅长的,我擅长的就是举例子,然后根据例子来聊。
首先来神奇的猜结果:
console.log(Function instanceof Function); console.log(Function instanceof Object); console.log(Object instanceof Object); console.log(Object instanceof Function);
大家猜一下结果?
透视true惊不惊喜意不意外。
首先来了解一下instanceof的是如何判断的。
instanceof
其实这个在前面聊三种判断数据类型,以及symbol类型的时候都说过。
看一下官网解释:
instanceof
运算符用于检测构造函数的 prototype
属性是否出现在某个实例对象的原型链上。
老规矩还是先用代码演示:
function Test(){}; var test=new Test(); test instanceof Test
这个原理是什么,其实前面聊过原型以及原型链,可以翻看我前面的文章:浅谈原型和原型链
现在看一下test和Test所谓的原型以及原型链。
从这个地方可以看出两者的广联,这个就有一个神奇操作了,其实在Symbol中的一个属性也演示过,现在再来一个演示:
function Test(){}; var test=new Test(); // 比如这样我们将其构造方法的原型修改了 Test.prototype={}; // 然后再这样操作一下 test instanceof Test
其实官网也这样说了:
需要注意的是,如果表达式 obj instanceof Foo 返回 true,则并不意味着该表达式会永远返回 true,因为 Foo.prototype 属性的值有可能会改变,改变之后的值很有可能不存在于 obj 的原型链上,这时原表达式的值就会成为 false。另外一种情况下,原表达式的值也会改变,就是改变对象 obj 的原型链的情况,虽然在目前的ES规范中,我们只能读取对象的原型而不能改变它,但借助于非标准的 __proto__ 伪属性,是可以实现的。比如执行 obj.__proto__ = {} 之后,obj instanceof Foo 就会返回 false 了。
当然如下操作也会返回错误:
function Test(){}; var test=new Test(); test.__proto__={}; // 然后再这样操作一下 test instanceof Test
所以说用instanceof具体逻辑用白话说: instanceof 返回结果从new 的对象上的原型链(__proto__)上是否有构造方法的原型(prototype)
。
所以如下:
function Test(){}; var test=new Test(); test instanceof Object
再如下看:
官网又这样说:
在浏览器中,我们的脚本可能需要在多个窗口之间进行交互。多个窗口意味着多个全局环境,不同的全局环境拥有不同的全局对象,从而拥有不同的内置类型构造函数。这可能会引发一些问题。比如,表达式 [] instanceof window.frames[0].Array
会返回 false
,因为 Array.prototype !== window.frames[0].Array.prototype
,并且数组从前者继承。
这个不再本篇讨论范围,简单的理解就是不同的window中的数组对象也是不同的。所以无法通过instanceof 进行判断。
现在知道了instanceof是如何实现的,现在看一下Function是什么?
Function
每个 JavaScript 函数实际上都是一个 Function
对象。运行 (function(){}).constructor === Function // true
便可以得到这个结论。
还是老规矩老代码演示:
function Test(){}; var test=new Test(); test.constructor===Test
然后再来一个:
//test 是一new 出来的对象 ,所以需要用 Test Test.constructor===Function
可以看出方法就是一个Function的对象。这样看是不是觉得稍微可以理解一些,当然这个也是由果推因。
还是老规矩,既然扯到官网,所以在补充官网的一个说明:
Function 构造函数与函数声明之间的不同:
由 Function 构造函数创建的函数不会创建当前环境的闭包,它们总是被创建于全局环境,因此在运行时它们只能访问全局变量和自己的局部变量,不能访问它们被 Function 构造函数创建时所在的作用域的变量。这一点与使用 eval() 执行创建函数的代码不同。如果想要了解闭包可以看我的另一个文章:浅谈AO,GO,闭包
来一个例子演示:
var x = 10; function createFunction1() { var x = 20; return new Function('return x;'); // 这里的 x 指向最上面全局作用域内的 x } function createFunction2() { var x = 20; function f() { return x; // 这里的 x 指向上方本地作用域内的 x } return f; } var f1 = createFunction1(); console.log(f1()); // 10 var f2 = createFunction2(); console.log(f2()); // 20
Object
Object 是 JavaScript 的一种 数据类型 。它用于存储各种键值集合和更复杂的实体。Objects 可以通过 Object() 构造函数或者使用 对象字面量 的方式创建。
简单的说:Object 构造函数创建一个对象包装器。Object构造函数为给定值创建一个对象包装器。如果给定值是 null 或 undefined,将会创建并返回一个空对象,否则,将返回一个与给定值对应类型的对象。 当以非构造函数形式被调用时,Object 等同于 new Object()。
简单的了解一些对象类型,可以看一下我的前面文章对象以及构造函数,当然这一篇文章只是简单说了一些对象类型。但是这个还有一个对象的创建方式不同方式,这个到时候再聊。
找一下Object 和Fuction的关系
前面说了instanceof的判断数据的关系,就是找对象的__proto__
和构造方法prototype的关系。首先说一下:构造函数都有prototype
//Function的原型对象 console.log(Function.prototype); //Object的原型对象 console.log(Object.prototype); //因为构造函数的prototype是一个对象 所以再搞一下是否能来一个原型链 console.log(Object.prototype.__proto__); console.log(Function.prototype.__proto__);
现在看一下具体呈现了什么?
似乎也没有什么关系啊,现在继续执行看:
这样一看就发现这个神奇的地方,那就是Object.prototype
和Function.prototype.__proto__
发现这两个竟然是一样的。
然后看一下是否真的相等:
console.log(Function.prototype.__proto__===Object.prototype);
然后再来一个神奇的测试,毕竟找到和对象的关系了,现在当作一对象试试:
Function.__proto__.__proto__
因此这个地方也就明白了:
console.log(Function instanceof Object);
这个也算也符号了对象的__proto__
和构造函数的prototype。
现在又要反过来看是否可行?
既然这样根据前面了解原型和原型链的可以知道:对象都会从它的原型上继承一个 constructor 属性.
function Test(){
}; var test=new Test(); // 然后看一下 console.log(test.constructor);
既然冲上面看出Object和Function的尽头都是对象,那么一下其构造函数:
console.log(Object.constructor); console.log(Function.constructor);
是不是发现一件神奇的事情,那就是两者的有一个关系,那么现在可以看一下是否两者相同:
console.log(Object.constructor === Function.constructor);
这个地方可以看出一件时间,那就是Object和Function的具有相同的构造函数。
根据前面test和Test的对比然后尝试一下:
Object.__proto__ === Function.prototype; //true
所以可以得到如下:
Function.prototype.__proto__ === Object.prototype;//true // 前面证明Function可以当作对象也可以如下 Function.__proto__.__proto__ === Object.prototype;//true Object.__proto__ === Function.prototype; //true
也就是复合了intanceof要求就是对象原型链和构造方法原型有相同的地方。
所以也就有了如下图(盗的图):
这个也就明白了为什么:
console.log(Function instanceof Function); //true console.log(Function instanceof Object);//true console.log(Object instanceof Object);//true console.log(Object instanceof Function);//true
今天的文章
function与object关系_javascript编程软件分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/80990.html