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 () { ...
随机推荐
- LAMP集群项目三 配置业务服务器
安装MySQL 参考脚本:CentOS6.5一键安装MySQL5.5.32(源码编译) 在备份服务器上配置rsync推送任务 在备份服务器上配置 /etc/rsyncd.conf #在所有的客户端都 ...
- oracle如何用sql查看触发器?
ORACLE查出表所有的触发器及触发器详细信息 一.查all_triggers表得到trigger_name Sql代码 select trigger_name from all_triggers w ...
- 升级PHP版本导致zabbix无法访问解决办法
故障现象:无法打开zabbix首页,提示缺少zabbix.conf配置文件 原因分析:升级yum安装php版本了,升级前卸载了原PHP5.4版本导致 解决办法: 重新安装zabbix yum inst ...
- HDU 5875 Function 大连网络赛 线段树
Function Time Limit: 7000/3500 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) Total ...
- Bootstrap CSS组组件架构的设计思想
w AO模式 Append Overwrite 附加重写
- Java SAX handle xml
https://www.journaldev.com/1198/java-sax-parser-example Java SAX Parser Example SAX Parser in java ...
- zipline风险指标计算 (empyrical模块)
概述 量化中,我们经常会遇到各种量化指标的计算,对于zipline来说,也会对这部分计算进行处理,由于指标计算的通用性比较强,所以,zipline单独封装了 empyrical 这个模块,可以处理类似 ...
- js Ajax 跨域请求
一.使用jsonp的方式(只支持get请求) 二.使用cors的方式(支持HTTP的大部分请求方式) 三.apache的转发(修改服务器配置) 没有试验,暂时不详细写!
- Yii2的主从数据库设置
项目做大了,数据库主从还是不可少的.使用Yii框架开发,如何设置数据库的主从呢?其实很简单. 先说一个主数据库服务器和多个从数据库服务器的情况,修改配置文件 config/db.php ,其中 sla ...
- scrapy之中间件
中间件的简介 1.中间件的作用 在scrapy运行的整个过程中,对scrapy框架运行的某些步骤做一些适配自己项目的动作. 例如scrapy内置的HttpErrorMiddleware,可以在http ...