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 相关文章推荐
javascript 文章截取部分无损html显示实现代码
May 04 Javascript
基于jquery的button默认enter事件(回车事件)。
May 18 Javascript
js nextSibling属性和previousSibling属性概述及使用注意
Feb 16 Javascript
jquery实现先淡出再折叠收起的动画效果
Aug 07 Javascript
Vue.js结合bootstrap实现分页控件
Mar 10 Javascript
jquery实现放大镜简洁代码(推荐)
Jun 08 jQuery
js canvas实现放大镜查看图片功能
Jun 08 Javascript
使用ajax的post同步执行(实现方法)
Dec 21 Javascript
vue项目强制清除页面缓存的例子
Nov 06 Javascript
js实现无限层级树形数据结构(创新算法)
Feb 27 Javascript
浅谈Vue3.0新版API之composition-api入坑指南
Apr 30 Javascript
实例讲解JavaScript 计时事件
Jul 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
如何跨站抓取别的站点的页面的补充
2006/10/09 PHP
一篇不错的PHP基础学习笔记
2007/03/18 PHP
php实现mysql同步的实现方法
2009/10/21 PHP
php实现在新浪云中使用imagick生成缩略图并上传的方法
2016/09/26 PHP
php中如何执行linux命令详解
2018/11/06 PHP
php使用自带dom扩展进行元素匹配的原理解析
2020/05/29 PHP
JS中类或对象的定义说明
2014/03/10 Javascript
javascript框架设计读书笔记之字符串的扩展和修复
2014/12/02 Javascript
node.js中的console用法总结
2014/12/15 Javascript
javascript动态创建表格及添加数据实例详解
2015/05/13 Javascript
整理JavaScript对DOM中各种类型的元素的常用操作
2016/05/05 Javascript
深入理解Javascript中的自执行匿名函数
2016/06/03 Javascript
flexslider.js实现移动端轮播
2017/02/05 Javascript
微信小程序 动态绑定数据及动态事件处理
2017/03/14 Javascript
详解vue与后端数据交互(ajax):vue-resource
2017/03/16 Javascript
Node.js利用debug模块打印出调试日志的方法
2017/04/25 Javascript
webpack3之loader全解析
2017/10/26 Javascript
vue中的适配px2rem示例代码
2018/11/19 Javascript
JS字典Dictionary类定义与用法示例
2019/02/01 Javascript
微信小程序开发技巧汇总
2019/07/15 Javascript
javascript将16进制的字符串转换为10进制整数hex
2020/03/05 Javascript
详细分析Node.js 多进程
2020/06/22 Javascript
[00:35]TI7不朽珍藏III——寒冰飞龙不朽展示
2017/07/15 DOTA
Python天气预报采集器实现代码(网页爬虫)
2012/10/07 Python
python处理文本文件并生成指定格式的文件
2014/07/31 Python
Python编程中装饰器的使用示例解析
2016/06/20 Python
python中利用xml.dom模块解析xml的方法教程
2017/05/24 Python
python逐行读写txt文件的实例讲解
2018/04/03 Python
对numpy.append()里的axis的用法详解
2018/06/28 Python
python字典的值可以修改吗
2020/06/29 Python
DERMAdoctor官网:美国著名皮肤护理品牌
2019/07/06 全球购物
联想C++笔试题
2012/06/13 面试题
学校消防安全责任书
2014/07/23 职场文书
2015年生活老师工作总结
2015/05/27 职场文书
Nginx访问日志及错误日志参数说明
2021/03/31 Servers
vue-treeselect的基本用法以及解决点击无法出现拉下菜单
2022/04/30 Vue.js