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 相关文章推荐
node.js中的fs.createReadStream方法使用说明
Dec 17 Javascript
JS实现自动定时切换的简洁网页选项卡效果
Oct 13 Javascript
轻松实现javascript图片轮播特效
Jan 13 Javascript
老生常谈jquery id选择器和class选择器的区别
Feb 12 Javascript
多个上传文件用js验证文件的格式和大小的方法(推荐)
Mar 09 Javascript
Vue2几种常见开局方式详解
Sep 09 Javascript
JS运动特效之完美运动框架实例分析
Jan 24 Javascript
jQuery中each方法的使用详解
Mar 18 jQuery
JavaScript变量声明var,let.const及区别浅析
Apr 23 Javascript
微信小程序chooseImage的用法(从本地相册选择图片或使用相机拍照)
Aug 22 Javascript
如何为vue的项目添加单元测试
Dec 19 Javascript
JavaScript中的执行环境和作用域链
Sep 04 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
加强版phplib的DB类
2008/03/31 PHP
PHP中几个可以提高运行效率的代码写法、技巧分享
2014/08/21 PHP
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 2611816 bytes)
2014/11/08 PHP
PHP IDE phpstorm 常用快捷键
2015/05/18 PHP
php分割合并两个字符串的函数实例
2015/06/19 PHP
PHP 开发者该知道的 5 个 Composer 小技巧
2016/02/03 PHP
微信支付开发动态链接Native支付
2016/07/12 PHP
php正则表达式基本知识与应用详解【经典教程】
2017/04/17 PHP
模拟jQuery中的ready方法及实现按需加载css,js实例代码
2013/09/27 Javascript
在线引用最新jquery文件的实现方法
2016/08/26 Javascript
nodejs个人博客开发第六步 数据分页
2017/04/12 NodeJs
一篇看懂vuejs的状态管理神器 vuex状态管理模式
2017/04/20 Javascript
详解Angular-Cli中引用第三方库
2017/05/21 Javascript
基于vue2框架的机器人自动回复mini-project实例代码
2017/06/13 Javascript
Express + Node.js实现登录拦截器的实例代码
2017/07/01 Javascript
EasyUI在Panel上动态添加LinkButton按钮
2017/08/11 Javascript
浅谈vuex之mutation和action的基本使用
2017/08/29 Javascript
JavaScript中使用参数个数实现重载功能
2017/09/01 Javascript
vuejs使用axios异步访问时用get和post的实例讲解
2018/08/09 Javascript
解决element UI 自定义传参的问题
2018/08/22 Javascript
Electron-vue脚手架改造vue项目的方法
2018/10/22 Javascript
vue+element+Java实现批量删除功能
2019/04/08 Javascript
vue项目打包后上传至GitHub并实现github-pages的预览
2019/05/06 Javascript
layer弹出层取消遮罩的方法
2019/09/25 Javascript
使用p5.js实现动态GIF图片临摹重现
2019/10/23 Javascript
Openlayers+EasyUI Tree动态实现图层控制
2020/09/28 Javascript
Windows下安装python2.7及科学计算套装
2015/03/05 Python
Python之数据序列化(json、pickle、shelve)详解
2019/08/30 Python
python线性插值解析
2020/07/05 Python
西安夏日科技有限公司Java笔试题
2013/01/11 面试题
小学优秀班集体申报材料
2014/05/25 职场文书
防邪知识进家庭活动方案
2014/08/26 职场文书
民政局副局长民主生活会个人整改措施
2014/10/04 职场文书
寻衅滋事罪辩护词
2015/05/21 职场文书
2015年妇幼卫生工作总结
2015/05/23 职场文书
mysql序号rownum行号实现方式
2022/12/24 MySQL