javascript Object与Function使用


Posted in Javascript onJanuary 11, 2010

如今的JavaScript再也不是以前被当做玩具的在网页上运行的花哨的脚本了。JavaScript已经逐渐标准化,作为一门真正的编程语言广泛地应用在Web开发上。因此,越来越多的人开始重新认识这门脚本语言,并在不断地探索关于JavaScript核心思想和实现原理,过程中遇到了一些非常混淆的问题。本文着重解释一个比较常见但是非常容易使开发人员或者是初学JavaScript的人非常混淆的问题,那就是两个核心构造函数Object和Function,他们之间到底有什么关系?为何instanceof运算符的返回结果会让你感到混淆?本文将为你一一道来。不过在这之前,我们需要先了解一些JavaScript中的概念和基本的运行机制。

JavaScript的对象体系结构

其实在JavaScript语言中,整个核心的体系结构都围绕着两个构造函数Object和Function来构建的。我将引用来自mollypages.org的一张JavaScript对象体系结构图来说明。
javascript Object与Function使用
instanceof 运算符
instanceof是一个二元运算符,如:A instanceof B. 其中,A必须是一个合法的JavaScript对象,B必须是一个合法的JavaScript函数 (function). 判断过程如下:
如果函数B在对象A的原型链 (prototype chain) 中被发现,那么instanceof操作符将返回true,否则返回false.
例如下面的代码会返回true.

// return true if specified function is found// in the object's prototype chain as a constructor.alert({} instanceof Object);

JavaScript中的原型链(prototype chain)机制
这里简单概括一下,因为这个话题需要很大篇幅去讨论,本文只是引用了这个概念,重点并非详细讨论该机制。
JavaScript中的原型(prototype)是和函数(function)紧密相连的,因为每个函数默认都会有一个属性叫prototype, 每一个通过函数和new操作符生成的对象都具有一个属性__proto__, 这个属性保存了创建它的构造函数的prototype属性的引用。这个__proto__对象就是实现原型链的核心对象。JavaScript是一门面向对象的编程语言,它的继承特性其实就是通过原型链机制来实现的。同时,instanceof运算符也需要在原型链的支持。我们举例说明:

代码

// create a custom constructor Foo 
function Foo() { 
} 
// create an insatnce of Foo 
var foo = new Foo(); // foo is an instance of Foo 
alert(foo instanceof Foo);// true 
// foo is also an instance of Object because 
// Foo.prototype is an instance of Object. 
// the interpreter will find the constructor 
// through the prototype chain. 
alert(foo instanceof Object);// true 
// Prototype chain of the object foo 
// 
// __proto__ __proto__ __proto__ 
// foo -----------> Foo.prototype -----------> Object.prototype -----------> null 
// But foo is not an instance of Function, because 
// we could not find Function.prototype in foo's 
// prototype chain. 
alert(foo instanceof Function);// false 
// However, its constructor Foo is an instance of 
// Function. 
alert(Foo instanceof Function);// true 
// it's also an instance of Object 
alert(Foo instanceof Object);// true 
// Prototype chain of the constructor Foo 
// 
// __proto__ __proto__ __proto__ 
// Foo -----------> Function.prototype -----------> Object.prototype -----------> null

从上面的代码来分析,我们不难得出这样一个结论:任何对象的原型链最后都能追溯到Object.prototype. 这也就是我们为什么说JavaScript中所有的对象都继承自Object的原因了。

为何Object instanceof Function和Function instanceof Object都返回true?
Object, Function, Array等等这些都被称作是构造“函数”,他们都是函数。而所有的函数都是构造函数Function的实例。从原型链机制的的角度来说,那就是说所有的函数都能通过原型链找到创建他们的Function构造函数的构造原型Function.protorype对象,所以:

alert(Object instanceof Function);// return true
与此同时,又因为Function.prototype是一个对象,所以他的构造函数是Object. 从原型链机制的的角度来说,那就是说所有的函数都能通过原型链找到创建他们的Object构造函数的构造原型Object.prototype对象,所以:

alert(Function instanceof Object);// return true
有趣的是根据我们通过原型链机制对instanceof进行的分析,我们不难得出一个结论:Function instanceof Function 依然返回true, 原理是一样的
1. Function是构造函数,所以它是函数对象
2. 函数对象都是由Function构造函数创建而来的,原型链机制解释为:函数对象的原型链中存在Function.prototype
3. instanceof查找原型链中的每一个节点,如果Function.prototype的构造函数Function的原型链中被查到,返回true
因此下面代码依然返回true

alert(Function instanceof Function);// still true

结论
1. 在JavaScript语言中,一切的一切都是对象,它们全部继承自Object. 或者说所有对象的原型链的根节点都是Object.prototype
2. 理解原型链机制在JavaScript中式如何工作的是非常重要的。掌握了它,不管一个对象多么复杂,你总能够轻而易举地将它攻破。

Javascript 相关文章推荐
jQuery实现购物车数字加减效果
Mar 14 Javascript
微信小程序 wxapp导航 navigator详解
Oct 31 Javascript
Jquery Easyui分割按钮组件SplitButton使用详解(17)
Dec 18 Javascript
原生js实现手风琴功能(支持横纵向调用)
Jan 13 Javascript
Vue.js使用$.ajax和vue-resource实现OAuth的注册、登录、注销和API调用
May 10 Javascript
除Console.log()外更多的Javascript调试命令
Jan 24 Javascript
elementUI select组件value值注意事项详解
May 29 Javascript
JavaScript实现身份证验证代码实例
Aug 26 Javascript
开发Node CLI构建微信小程序脚手架的示例
Mar 27 Javascript
前端开发基础javaScript的六大作用
Aug 06 Javascript
React冒泡和阻止冒泡的应用详解
Aug 18 Javascript
vue created钩子函数与mounted钩子函数的用法区别
Nov 05 Javascript
Extjs学习笔记之九 数据模型(上)
Jan 11 #Javascript
JavaScript 事件冒泡简介及应用
Jan 11 #Javascript
Javascript 读书笔记索引贴
Jan 11 #Javascript
Javascript学习笔记9 prototype封装继承
Jan 11 #Javascript
Javascript学习笔记8 用JSON做原型
Jan 11 #Javascript
Javascript学习笔记7 原型链的原理
Jan 11 #Javascript
Javascript学习笔记6 prototype的提出
Jan 11 #Javascript
You might like
php去掉字符串的最后一个字符附substr()的用法
2011/03/23 PHP
三种php连接access数据库方法
2013/11/11 PHP
php获取服务器端mac和客户端mac的地址支持WIN/LINUX
2014/05/15 PHP
smarty内置函数section的用法
2015/01/22 PHP
thinkPHP内置字符串截取函数用法详解
2016/11/15 PHP
PHP+fiddler抓包采集微信文章阅读数点赞数的思路详解
2019/12/20 PHP
javascript 跳转代码集合
2009/12/03 Javascript
js兼容的placeholder属性详解
2013/08/18 Javascript
js实现弹窗插件功能实例代码分享
2013/12/12 Javascript
自编jQuery插件实现模拟alert和confirm
2014/09/01 Javascript
node.js入门实例helloworld详解
2015/12/23 Javascript
很不错的两款Bootstrap Icon图标选择组件
2016/01/28 Javascript
关于JS中二维数组的声明方法
2016/09/24 Javascript
jQuery Easyui加载表格出错时在表格中间显示自定义的提示内容
2016/12/08 Javascript
vue获取dom元素注意事项
2017/12/28 Javascript
nodejs前端模板引擎swig入门详解
2018/05/15 NodeJs
详解使用mpvue开发github小程序总结
2018/07/25 Javascript
详解从react转职到vue开发的项目准备
2019/01/14 Javascript
js观察者模式的弹幕案例
2020/11/23 Javascript
python教程之用py2exe将PY文件转成EXE文件
2014/06/12 Python
Python with的用法
2014/08/22 Python
Python socket.error: [Errno 98] Address already in use的原因和解决方法
2014/08/25 Python
python将unicode转为str的方法
2017/06/21 Python
Python设计模式之命令模式简单示例
2018/01/10 Python
python正则表达式面试题解答
2020/04/28 Python
python 机器学习之支持向量机非线性回归SVR模型
2019/06/26 Python
浅谈spring boot 集成 log4j 解决与logback冲突的问题
2020/02/20 Python
Pytorch 使用 nii数据做输入数据的操作
2020/05/26 Python
python如何变换环境
2020/07/21 Python
名词解释WEB SERVICE,SOAP,UDDI,WSDL,JAXP,JAXM;JSWDL开发包的介绍。
2012/10/27 面试题
Ado与Ado.net的相同与不同
2014/12/08 面试题
行政工作个人的自我评价
2014/02/13 职场文书
2015年学生会干事工作总结
2015/04/09 职场文书
《浅水洼里的小鱼》教学反思
2016/02/16 职场文书
详细了解MVC+proxy
2021/07/09 Java/Android
MySQL常见优化方案汇总
2022/01/18 MySQL