JS对象深入剖析
对象概述
Objects are mutable keyed collections.
An object is a container of properties, where a property has a name and a value.
A property name can be any string, including the empty string.
A property value can be any JavaScript value except for undefined.
一般对象
Object includes a prototype linkage feature that allows one object to inherit the properties of another.
这里,这个原型链接(a prototype linkage)是隐藏的(在Debugger里面看不见的),在某些实现中,它的属性名是__proto__

任何一个对象的__proto__链接都是不为空的,对于一个从Object Literal中创建的对象,其__proto__指向Object.prototype。只有Object的prototype的_proto_指向为null。
有了__proto__链接之后,就可以发挥一些面向对象的威力了,头一个就是Delegation。Delegation是指当从一个对象中获取一个属性失败时,JS会自动再尝试去其__proto__链接指向的对象中去查找,如果还找不到,就沿着__proto__一路找上去,指导找到Object.prototype为止。根据上述Delegation算法的描述,你可以很容易理解Delegation过程是动态的,这次可以从祖先中找到A属性,不代表下次一定能找到。
这里需要注意的是,__proto__链接只对查询有效,而对Update无效,也就是说,如果你给一个属性赋值的话,而这个属性在该对象中还不存在,而在__proto__祖先中已有同名属性,但这是JS会在该对象中再新建一个属性,而不是修改祖先的属性值
函数对象
函数对象首先是一个对象,所以,它也有__proto__链接,也有Delegation。函数对象还有一个特殊之处就是它会有一个叫做prototype的属性。
当用var a = function(){}定义一个函数时,JS会生成一个函数对象,这个函数对象的__proto__指针指向Function.prototype。同时还会有一个prototype属性,其值是一个对象,这个对象只有一个属性是构造函数,构造函数的值就是这个函数的定义function(){},而这个对象(prototype)的__proto__指针则指向Object.Prototype。

了解了函数对象,再看看它如何发挥作用:当用new激活一个函数时,一个新对象会被创建出来,其内容是执行函数的返回结果,而这个对象的__proto__链接指向函数的prototype属性对象。

创建对象Object.Create
Object.create = function (o) {
var F = function () {};
F.prototype = o;
return new F();
};
var b = Object.create(a);
首先,在执行var b = Object.create(a)之前,已经有了a对象,在执行了var F = function () {}之后,F函数对象被创建出来,F的prototype属性也被赋值指向一个新创建出来的对象,执行了F.prototype = o; 之后, F的prototype属性指向了对象A,执行new F();之后,即当用new激活一个函数时,一个新对象会被创建出来,其内容是执行函数的返回结果,而这个对象的__proto__链接指向函数的prototype属性所引用的对象。
最后,我们可以得出,对象的__proto__链接是不能直接修改的,而函数对象的prototype属性是可以修改的,因此,Object.create实际上是利用了这个特点,结合new来完成了一个拷贝创建的过程。
Scope和Closure
对于一个JS程序而言,都有一个Global Scope Object, 我们定义的全局变量,其实都是这个对象的属性,在主程序体中,可以用this来访问这个对象的内容。这时Scope Chain当中只有一个Global Scope Object。
var Counter = function() {
var value = 0;
return {
increment : function(inc) {
value += typeof(inc) === "number" ? inc : 1;
},
getValue : function() {
return value;
}
}
}
var counter1 = new Counter();
var counter2 = new Counter();
counter1.increment();
counter1.getValue();
counter2.getValue();
Scope原则1: 当函数Counter被定义时,JS会把当前有效的Scope Chain保存在函数对象当中备查。
Scope原则2:当一个函数被执行时,会创建一个新的Scope Object,再将函数内容完全分析一遍,将参数和局部变量都加成新Scope对象的属性,最后将新Scope Object作为Scope Chain的最后一节,更新Scope Chain。
执行完var Counter = function() {…}之后,触发原则1,执行var counter1 = new Counter;后触发原则2。
Scope Chain的作用在于之后查找属性时,如果本Scope查不到,就去父Scope里面查,指导Global Scope Object。感觉其实也是Delegation,所以说不定Scope Object之间也是用__proto__来连接的。
之后Counter的内容被执行,increment和getValue两个函数被定义,之后被返回给counter1。
一个函数F的内部函数G可以访问F定义的局部变量和参数,这就叫闭包,它是在JS中实现封装的基础。
JS对象深入剖析的更多相关文章
- js对象详解(JavaScript对象深度剖析,深度理解js对象)
js对象详解(JavaScript对象深度剖析,深度理解js对象) 这算是酝酿很久的一篇文章了. JavaScript作为一个基于对象(没有类的概念)的语言,从入门到精通到放弃一直会被对象这个问题围绕 ...
- JS对象继承篇
JS对象继承篇 ECMAScript只支持实现继承,而且其实现继承主要是依靠原型链来实现的 原型链 其基本思路是利用原型让一个引用类型继承另一个引用类型的属性和方法 function Person() ...
- JS 对象封装的常用方式
JS是一门面向对象语言,其对象是用prototype属性来模拟的,下面,来看看如何封装JS对象. 常规封装 function Person (name,age,sex){ this.name = na ...
- JSON字符串和JS对象之间的转换
JSON字符串和JS对象之间的转换 1 json字符串转换为js对象 1.1 标准json格式字符串转换为Js对象 JSON字符串 str JSON.parse(str) eval(str) eva ...
- js 对象的_proto_
js 对象呢,有个属性叫_proto_,以前没听说过,也没关注,最近看这个原型,就被迫知道了这个东西,js 这里面的东西,真是规定的很奇怪,具体为啥也不知道,就测试发现的,对象的_proto_属性,和 ...
- js对象/数组深度复制
今天碰到个问题,js对象.数组深度复制:之前有见过类似的,不过没有实现函数复制,今晚想了一下,实现代码如下: function clone(obj) { var a; if(obj instanceo ...
- js对象的深度克隆
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- js对象详解
js自定义对象 一,概述 在Java语言中,我们可以定义自己的类,并根据这些类创建对象来使用,在Javascript中,我们也可以定义自己的类,例如定义User类.Hashtable类等等. 目前在J ...
- js对象常用2中构造方法
//js 对象的构造方法通常有2中情况: //第一种是通过json对象构造 var persion={ name:"孙悟空", age:40, eat:function () { ...
随机推荐
- 解决 Unable to load native-hadoop library for your platform
安装hadoop启动之后总有警告:Unable to load native-hadoop library for your platform... using builtin-java classe ...
- java枚举类型(转载)
public class TestEnum { /*最普通的枚举*/ public enum ColorSelect { red, green, yellow, blu ...
- js根据数组对象中某个元素合并数组
一个数组,根据数组中某个元素,合并数组 // 需要被合并的数组,把Index相同的数组合并 const arr = [{id:0,name:'张三'}, {id:0,name:'李四'}, {id:1 ...
- 160329(二)、web.xml配置详解
1.启动一个WEB项目的时候,WEB容器会去读取它的配置文件web.xml,读取<listener>和<context-param>两个结点. 2.紧急着,容创建一个Servl ...
- IPTABLES简介
iptables防火墙工作原理 简介:iptables防火墙工作在网络层,针对TCP/IP数据包实施过滤和限制,iptables防火墙基于内核编码实现,具有非常稳定的性能和高效率: iptables属 ...
- iOS 10 获取相册相机权限
AVAudioSession *audioSession = [[AVAudioSession alloc]init]; [audioSession requestRecordPerm ...
- INFORMATION_SCHEMA.STATISTICS 统计 表 库 大小
INFORMATION_SCHEMA MySQL :: MySQL 5.5 Reference Manual :: 21 INFORMATION_SCHEMA Tables https://dev.m ...
- 苏宁易购微信端 全页通过background单图
w单图,绕开了显示的兼容性. http://res.m.suning.com/project/JoinGo/intro.html http://res.m.suning.com/project/Joi ...
- Qt JSON解析生成笔记(把JSON转成一个类对象)
对于这样一段json { "name": "布衣食", "gender": "Male", "age" ...
- 十個必用的 Vim Plugin
◎ The NERD Tree 操作 Vim 時,通常都在 Terminal 底下作用,無法像一般的 GUI 應用程式可以以樹狀目錄來瀏覽檔案. The NERD Tree 是一將檔案目錄 ...