这篇是 上篇 固有对象和非固有对象的成员,值类型赋值,非值型引用的差异
的继续.
首先我们这里说固有对象就是 布尔值
字符串
数值
通用对象
数组
函数
(未定义
空值
太特殊,就不提了
)
对应的对象就是 Boolean,String,Number,Object,Array,Function(这几个字母在这里指的是对象,不是指类型表示,这几个对象的类型都是 function/函数 )
还记得上篇中说的
无法对
值类型赋予新的可变成员
布尔值
字符串
数值
就是值类型, Boolean,String,Number 不是值类型,是function
这个绕嘴的说法都是因为文字上的写法造成的,我们用 小写 boolean,string,number (其实javascript也就是这么表示的)或中文的布尔值,字符串,数值表示类型,Boolean,String,Number表示JavaScript 的3个对象.
所以:
/*以下有效*/
Boolean.foo='foo';
String.foo='foo';
Number.foo='foo';
Object.foo='foo';
Array.foo='foo';
Function.foo='foo';
/*以下无效*/
'string'.foo='foo';
(1).foo='foo';
true.foo='foo';
下面看看用prototype(原型定义)方法扩展对象在使用上的差别:
String.prototype.foo='foo';
var v=new String('string');
v.foo=3;
alert(v.foo);//3
var v='string';
v.foo=3;
alert(v.foo);//foo
噢,原来new这个关键字用和不用还是有差别的,同样的道理也适用于Boolean,Number,但是:
Object.prototype.foo='foo';
var v=new Object();
v.foo=3;
alert(v.foo);//3
var v={};
v.foo=3;
alert(v.foo);//3,原型都被改了
Object.prototype.foo={v:'foo'};//非值对象也同样
var v={};
v.foo.v=3;
alert(v.foo.v);//3
var v={};
alert(v.foo.v);//3,原型都被改了
进一步:
String.prototype.foo={v:'foo'};
var v=new String('string');
v.foo.v=3;
alert(v.foo.v);//3
var v='string';
alert(v.foo.v);//3,原型都被改了
值对象和非值对象就是不一样.
好像有些乱,我也没有找到合适的语言来组织这个
var v=new String('string');//和
var v='string';//以及
String.prototype.foo={foo:'foo'};//对JavaScript内建 string的影响到底如何描述
不过对于非固有对象
也就是对象
就没有那么复杂了,
var foo=function(){};
foo.prototype={v:'foo',foo:{v:'foo'}};
var o=new foo;
o.v=3;
o.foo.v=4;
var o =new foo;
alert(o.v);//foo
alert(o.foo.v);//,原型都被改了
原因很简单,因为foo.prototype只不过由于名称的特殊,会让JavaScript对new 操作进行特殊的继承处理,除此之外,
foo.prototype也具有普通对象的特性,符合值类型拷贝副本
,非值型引用
的规律
那容易让人迷惑的o.foo.v的v不也是值类型
么?是可是别忘了前面的foo是非值型
,
o.foo.v
中的foo已经指向
了 foo.prototype.foo
当然o.foo.v
和foo.prototype.foo.v
是同一个
对象了
同样道理:由于
var o=new foo;
o是foo的一个实例,是两个对象,那
o!=foo;
o!=foo.prototype;
o.v!=foo.prototype.v;//因为是值类型
o.foo===foo.prototype.foo;//非值型
非值类型就引用到同一内存对象上了.
不过非值型的赋值也有意思,就是改变的是引用,而不是单纯的改变值.
var foo=function(){};
foo.prototype={v:'foo',foo:{v:{v:'foo'}}};
var o=new foo;
o.v={};
o.foo.v={v:'new'};
var o =new foo;
alert(o.foo.v.v);//原型都被改了
这回原型又被改了.这样
var foo=function(){};
foo.prototype={v:'foo',foo:{v:{v:'foo'}}};
var o=new foo;
o.v={};
o.foo={v:'new'};
var o =new foo;
alert(o.foo.v.v);//没有被改
一会儿改一会儿不改,到底问题在哪里,差别在哪里问题就在那里:
差别在:
o.foo={v:'new'};
o.foo.v={v:'new'};
注意o是独立的实例对象,o.foo是引用,和 foo.prototype.foo是同一个对象.直接对o.foo赋值当然改变的是引用,掐断了引用,引用到一个新的对象了,和原来的foo.prototype.foo不一样了,虽然
{v:'foo'}
也是一个对象,不过要注意o.foo.v中的foo已经明确范围
,这个范围就是同一个对象,当然原型也被改了.回头再看看前面的o,
哈哈,原来o是个新的实例,范围不同
呀!同样适用这个确定范围的说法
说了这么多,其实就一句话,引用的问题,先
确定范围
吧,是不同的,还是相同的.
如果用标准的说法这是个Scope Chain的问题.抄一段规范的翻译文章:
http://www.cnblogs.com/winter-cn/archive/2008/07/07/1237168.html 写道
1. 获取Scope Chain的下一个对象。如果没有对象了,则转到第5步。
2. 调用结果(1)的[[HasProperty]]方法, 传递Identifier作为参数
3. 如果结果(2)是true, Reference(引用)类型的值,它的base object是结果(1)而它的
property name是Identifier
4. 跳到第1步
5. 返回一个Reference类型,它的base object是null它的property name 是Identifier.
注:Reference(引用)类型的值是JS引擎使用的一种数据类型,它分为base object和property name两个部分。假设在JS代码中有obj.prop这样的表达式,那么解释成Reference类型,base object是对象obj,而property name是字符串”prop”
Scope Chain开始时被设为宿主对象,所以在全局代码中的变量就是宿主对象的属性。Scope Chain在执行时由JS引擎自动维护,编译型的引擎也会创建相应的运行时环境来做此事。Scope Chain一般在函数调用或者执行进入with块的时候改变。
说起来麻烦,用起来其实很简单.
还有一点是在JavaScript里继承这个词不是很准确,连祖先都随时可以被修改,这那是继承,明显是颠覆嘛!所以我觉得用Mixin
混入来说更合适,也无所谓,反正大家都知道在JavaScript里说的都是一回事.
分享到:
相关推荐
1. **使用DOM属性和特征检查**:DOM对象有一些固有的属性,比如nodeType属性和tagName属性。如果一个对象有nodeType属性且其值为1(表示一个元素节点),或者有tagName属性(表示是一个元素节点的标签名),那么它很...
- 而“可绘制”或“可移动”的行为则适合定义为接口,因为不同的图形对象都需要实现这些行为,但这些行为并不是它们的固有属性。 综上所述,Java 抽象类和接口在面向对象编程中各有其优势和适用范围。选择使用哪一...
然而,对象和关系数据库之间存在固有的不匹配,被称为对象-关系阻抗失配(Object-Relational Impedance Mismatch),这是由于对象的面向对象特性(如封装、继承)与关系数据库的表格结构之间的差异造成的。...
Prototype的核心目标是通过提供一套丰富的实用函数和类,来解决JavaScript语言的一些固有问题,如作用域、继承和事件处理等。 **主要特性** 1. **对象扩展与函数增强**: Prototype扩展了JavaScript的基本类型和...
ASP.Net和ASP是两种Microsoft开发的Web应用程序框架,它们在技术特性和开发方式上存在显著差异。ASP(Active Server Pages)是1996年推出的技术,主要用于创建动态交互式的Web页面,它允许开发者在HTML中嵌入...
在C++和Java中,多态的实现方式略有差异,但它们都有相同的目标,即提供一种灵活的机制,使得代码能处理多种类型的对象,而无需知道对象的确切类型。C++的多态主要依赖于虚函数,而Java的多态是语言的固有特性,无需...
4. 实践决定认识:第二道试题中,虽然提到了实践水平与认识能力的关系,但主要强调的是主体差异性,而非实践对认识的决定作用。 5. 文化创新与人民需求:第三道试题涉及文化创新,强调了创新主体要有文化自觉和担当...
通过这些题目和解析,我们深入理解了C++中的各种概念,包括变量、引用、指针、数据类型、运算符、函数、类与对象、继承、多态性、异常处理、输入输出、字符串处理以及C++的标准库函数等。掌握这些知识点对于学习和...
11.3 静态和非静态的方法.129 11.4 方法的重载.130 11.5 操作符重载.134 11.6 小 结.137 第十二章 域 和 属 性 .139 12.1 域 .139 12.2 属 性 .143 12.3 小 结 .146 第十三章 事件和索引指示器 .148 ...
4. **频数分布直方图**:这是一种用长方形的高度表示频数与组距比的统计图表,能清晰展示各组频数分布和差异。 5. **必然事件和不可能事件**:必然事件是在任何条件下都会发生的事件,其概率为1;不可能事件是在...
解构主义的核心在于质疑和挑战传统理论中的固定结构和确定性,特别是对于文本意义的固有理解。德里达提出,文本的意义并非静态、封闭的,而是动态的、开放的,充满了延异(différance),即意义总是不断地被延迟和...
古代德育虽有局限,但其中的精华部分如人文精神、教育智慧,可以批判继承和创新应用。 8. **品德的要素**:品德由知识、情感、意志和行为四个要素构成。这四个方面相互作用,共同推动品德的形成和发展。通过教育,...
for...in语句是JavaScript中用于遍历对象属性的一种方式,它能够遍历对象的可枚举属性,包括对象自身的和继承的。然而,for...in语句并不是完美无缺的,它存在一些缺陷,尤其是在进行跨浏览器开发时,这些问题尤为...
在化工厂的聚合温度控制中,PID控制器能够根据当前温度和设定目标温度之间的差异来调节冷却水和蒸汽阀门的开度,从而达到温度控制的目的。 然而,传统的PID控制器存在一些固有的局限性,比如难以处理高扰动情况、超...
五轴并联机器人数控加工机床继承了并联机器人和数控机床的优势,能够实现五轴联动,即在同一台机床上能够实现工件的X、Y、Z三个方向的直线运动以及A、B两个旋转轴的转动,这为加工复杂形状的零件提供了可能。...
2. 忽视直播电商缺陷:电商直播平台的发展存在一些固有问题,如产品同质化和直播方式同质化等。这些问题若不妥善处理,将严重影响农产品直播电商的效果。产品同质化意味着产品之间缺乏差异化特征,不易形成品牌独特...
1. 固有思维突破:企业需要打破传统的营销模式,培养创新思维,引入现代化的营销理念和工具,以适应快速变化的市场环境。 2. 强化品牌故事:通过讲述品牌背后的故事,增强消费者的情感连接,提升品牌忠诚度。 3. ...
孟子继承和发展了孔子的思想,提出了“浩然之气”的概念,强调内心的道德力量和社会责任感。他并没有特别强调“谨言”,而是更注重内心的修养和道德实践。 6. **“天命之谓性”的来源** 这句话出自《中庸》,是...
- 选项 A (`移动互联网是 PC 互联网的别称`) 是不正确的,移动互联网与 PC 互联网虽然都属于互联网范畴,但它们的服务模式和技术实现存在差异。 - 选项 B (`移动互联网是将移动通讯和互联网二者结合起来`) 是正确...