- 浏览: 181706 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
abc20899:
对啊!报错!楼主你测试了吗?
Java7 - 新特性之对集合类的语言支持 -
zskangs1126:
Facebook 的系统架构 -
ccxiajie:
List list={"hello"}; ...
Java7 - 新特性之对集合类的语言支持 -
luoyahu:
请不要把你的兴趣变成工作,因为那样会毁了你的兴趣。
一些对程序员的建议(不要轻易的让人帮你决定,那怕是你的家人) -
coral0212:
我也尝试创过业,但我觉得我这种人是“谋士”,不是能攻城拔寨的“ ...
一些对程序员的建议(不要轻易的让人帮你决定,那怕是你的家人)
javascript中包含6种数据类型:undefined、null、string、number、boolean和object。其中,前5 种是原始数据类型,object是对象类型。 object类型中包括Object、Function、String、Number、Boolean、Array、Regexp、Date、 Globel、Math、Error,以及宿主环境提供的object类型。 通常在javascript中进行类型判断主要通过3种方式:typeof、instanceof、constructor。 typeof操作可能返回的类型为undefined、object、number、string、function、boolean。但是会有一些情况并不能完全判断准确。比如typeof new String('')的值为object。 有时候我们可能会很偷懒的使用a.constructor == String进行类型判断,但是constructor其实是不靠谱的东西。因为当我们调用a.constructor的时候,内部操作其实是 ToObject(a).prototype.constructor(ToObject是什么,看下文分解)。 看下面一段代码就能明白: 或者 而且,通过constructor并不能判断出对象实例类型的继承关系。因为javascript的继承其实是通过原型链实现的(原型链是什么,看下文分解)。 另外,null.constructor会抛出运行时的TypeError,所以使用constructor除了不靠谱外,还可能伴随着异常的风险。 例子:a instanceof String 关于object类型的判断,使用instanceof判断是比较靠谱的方法。instanceof所做的事情是,先取出类型对象(String) 的prototype成员(String.prototype),然后和要判断类型的对象(a)的原型链中的对象逐个比较。当发现是一个对象的时候返回 true,原型链中当前节点是null的时候返回false。 类型判断示例:判断一个变量是否是字符串类型 ecma262中描述了以下几种类型转换的操作:(还有其他的比如ToInt32等,这里就不列了) 每种操作都描述了从什么类型转换成该类型的映射。比如上文的'a'.constructor中,就包含解析器使用ToObject将‘a’转换成 object的一个隐式操作。 这里想要主要说的是ToPrimitive。ToPrimitive用于转换成原始数据类型。当要转换的量已经是原始类型时,会直接返回。如果要转换的是一个Object,那会调用[[DefaultValue]]方法做转换。([[DefaultValue]]是什么,下文分解)该方法可以传入一个hint参数,说明需要将Object转换成字符串或数字。如果要转换成字符串,则调用Object的toString方法,如果要转换成数字,则调用 Object的valueOf方法。具体在运行时什么时候应该转换成什么类型,请参考ecma262中关于expression的描述部分。 ------------------- 切割线:写累了,喝点水去 ---------------------- 除了5种原始类型外,一切都是Object,包括Object、Function、Array等等,他们的实例和构造器,都是Object。那 Object是一个什么东西呢? Object是一个:无序的成员集合 它是一个集合,说明它包含0-n个成员。而它是无序的。 每一个成员由以下3个部分组成:名称、值、特征集合 下面的代码中: key就是成员名称,value就是值,obj这个Object从代码上看起来包含了一个成员,注意,是从代码上看而已。这里我们不去深究它先。 那特征集合是个什么东西呢? javascript的对象成员可能包含下面几种特征的0个或多个:ReadOnly、DontEnum、DontDelete、 Internal。 一个对象的Internal成员以[[xxxx]]的方式来表示。 下面列一些和本博有关的的Object可能包含的internal成员。 ------------------- 切割线:手开始酸了 ---------------------- 解析器在遇到function declaration或者function expression的时候,会创建一个function Object。步骤大致如下: 在这个创建过程里,要说明的几点是: 还要提的一点是,function declaration和function expression是不一样的 function declaration: function expression: ------------------- 切割线:坐着怎么那么热呢 ---------------------- 首先要澄清的一点是,我们通常会使用myfunction.prototype的方式进行原型扩展,所以我们在听到“原型链”这个词的时候,会觉得这里的“原型”指的是myfunction.prototype。其实不是,“原型”指的是对象的[[Prototype]]。当然,对象的 [[Prototype]]就是其真实构造器当前的prototype成员对象。 上文中有提过,一个我们通过程序创建的function Object,一定会包含[[Call]]和[[Construct]]这2个internal成员。它们做了什么事情呢? [[Call]]: [[Construct]]: 一切都很清楚了。当我们创建一个对象,也就是我们new的时候,调用的是function Object的[[Construct]]成员方法。在上面的描述中,3、4步描述了[[Prototype]]成员的创建过程,就是构造器的 prototype成员。 好的,那回到之前,我们使用obj.property来获取obj对象的属性的时候,其实调用的是obj对象的internal方法 [[Get]]。那我们看看[[Get]]方法调用做了哪些事情: 可以看出来,当我们获取对象obj的某个成员的时候,会在obj对象自身成员里查找是否存在该成员。如果不包含,则到obj. [[Prototype]]这个对象中查找名字成员,如果还不存在,则到obj.[[Prototype]].[[Prototype]]这个对象里找,直到某个[[Prototype]]是null为止。查找的过程就是一个顺藤摸瓜的事情,这个藤就是我们所谓的“原型链”。 我不想说太多原型链和继承之间的关系与实现,这方面的资料在网络上已经太多太多。我只想把原型链脱光了告诉大家,原型链是什么。 ------------------- 切割线:脑子发胀中 ---------------------- 讲到作用域链,就要扯到函数的调用。当我们有一个函数 我们去调用它 这个时候解析器为我们做了什么呢? 有一定经验的javascript工程师也许会用过arguments、用过闭包、知道作用域,这一切的一切,都和execution context有关。 当我们进入一个函数调用的时候,解析器会为我们创建一个活动对象(Activation Object ),假设这里把这个活动对象叫做ac(为什么不叫ao呢,因为喜欢c)。然后做下面的事情: 那scope chain是什么作用呢?看下面的描述,来自10.1.4 During execution, the syntactic production PrimaryExpression : Identifier is evaluated using the following algorithm: 在程序正常在全局下的函数,其[[scope]]成员的值是global object,所以无论任何调用,在作用域链的尾端,一定会是global object。在浏览器宿主环境下,就是window。 ------------------- 切割线:感叹中,怎么还没写完,唠唠叨叨的,受不了自己了 ---------------------- 在函数的调用中,this是个什么东西,又是由什么决定的呢?在ecma262中,这是个比较绕的东西,其描述散落在世界各地。 首先,在10.2.3中告诉我们: The caller provides the this value. If the this value provided by the caller is not an object (note that null is not an object), then the this value is the global object. 我们可以知道,caller可以提供给我们this。如果没有提供,则this为global object。问题又来了,caller是怎么提供this的? 在11.2.3中,找到如下关于Function calls的描述:The production CallExpression : MemberExpression Arguments is evaluated as follows: 从步骤6、7中可以看出来,如果MemberExpression的结果是一个Reference的话,提供的this应该是 GetBase(Reference),否则是空。步骤7中还有描述了6的结果是活动对象的情况,我们这里忽略。 又有疑问了,Reference?Reference是什么,GetBase又是什么? 我们在8.7中,找到了Reference的答案。这里的描述比较长,我只摘了可以满足我们需要的一段: A Reference is a reference to a property of an object. A Reference consists of two components, the base object and the property name. The following abstract operations are used in this specification to access the components of references: GetBase(V). Returns the base object component of the reference V. GetPropertyName(V). Returns the property name component of the reference V. 已经很明显了,一个Reference必须引用一个对象的一个属性。所以我们通过obj.method()来调用的时候,obj.method这个表达式生成了一个中间态的Reference,这个Reference的base object就是obj,所以GetBase的结果就是obj,于是obj被caller提供作this 我曾经看到很多文章,举了类似obj.method()这样的调用例子,认为obj就是caller,来解释这番话: The caller provides the this value. If the this value provided by the caller is not an object (note that null is not an object), then the this value is the global object. 这其实是说不通的。 caller绝不可能是obj,否则被attachEvent的函数或对象方法,他们运行时的this就解释不通了。 所以,通过我们自己代码调用的函数,caller由脚本引擎执行控制所决定;在浏览器宿主环境通过事件触发的,caller由浏览器控制的行为所决定。 ------------------- 切割线:坚持坚持,好不容易想写点正经东西,快了 ---------------------- 这个问题是telei同学提出的。答案是:不会 回头看看[[Construct]]的步骤,我们可以发现,创建一个对象obj时,obj.[[prototype]]成员被赋予其构造器的 prototype成员。但是当构造器的prototype成员被指向为另外一个对象的引用时,obj.[[prototype]]依然是其构造器的前 prototype对象。 描述代码如下:(注释里是说明) 最后特殊的解释:好吧,上面代码的最后出现了很搞笑的事情,合乎语言的实现,但不合乎正常以及不正常地球人的逻辑。 我们知道,a对象是被A构造器创建出来的,所以a是A的实例。 但是,上面类型判断那里有讲,instanceof是通过构造器prototype成员与对象原型链的比较来判断的。所以当对象a被创建后,如果创建它的构造器的prototype发生了变化,a就和他妈(构造器)没任何关系了。 看到这里,你确定你还想要在实例化对象后,修改构造器的prototype成另外一个对象吗? ------------------- 切割线:我是结束前 ---------------------- 好了,就写这么多吧,好久不码那么多字了………… 渴了,有没有人请我喝饮料~~1. 数据类型
2. 类型判断
2.1 typeof
2.2 constructor
String
.
prototype
.
constructor
=
Number
;
alert
(
'test'
.
constructor
==
String
);
//Result:false
function
MyClass
()
{
}
MyClass
.
prototype
=
{};
alert
((
new
MyClass
).
constructor
==
MyClass
);
//Result:false
2.3 instanceof
function
isString
(
str
)
{
return
(
typeof
str
==
'string'
||
str
instanceof
String
);
}
3. 类型转换
4. Object
var
obj
=
{
'key'
:
'value'
};
5. function Object的创建过程
function
fn
()
{}
var
a
=
function
()
{};
function
()
{};
6. 原型链
7. 函数调用过程与作用域链
function
fn
(
param
)
{}
fn
(
1
);
8. 函数调用过程中的this
9. 关于原型链的补充——原型链会不会是圆形链
function
A
(){
this
.
testA
=
new
Function
();
}
function
B
(){
this
.
testB
=
new
Function
();
}
var
a
=
new
A
();
B
.
prototype
=
a
;
//a.[[prototype]] == {};(不是真的等,{}表示的是Function A初始的prototype object。下同)
var
b
=
new
B
();
//b.[[prototype]] == a;
//b.[[prototype]].[[prototype]] == a.[[prototype]] == {};
A
.
prototype
=
b
;
var
a2
=
new
A
();
//a2.[[prototype]] == b;
//a2.[[prototype]].[[prototype]] == b.[[prototype]] == a;
//a2.[[prototype]].[[prototype]].[[prototype]] == b.[[prototype]].[[prototype]] == a.[[prototype]] == {};
//最后测试一下,很搞笑的
alert
(
a
instanceof
A
);
发表评论
-
HTML代码的美感(翻译)
2010-07-30 17:04 1279每当我访问精美的网站,我都情不自禁地会去查看源代码。这 ... -
网页设计中HTML常犯的五个错误
2010-07-30 16:54 8991.网页背景色的设置 犯错机率:很大 普遍性:较广 犯 ... -
javascript 使用Cookies
2010-07-30 16:49 771在 document 对象中有一个 cookie 属性。但是 ... -
HTML 5与Flash技术优缺点大比拼
2010-06-17 16:50 1088文字来源:AFITY开源社区 http://www.afi ... -
web超酷的图片效果
2009-01-23 04:04 890<!DOCTYPE HTML PUBLIC &qu ...
相关推荐
JavaScript中的引用类型主要涉及到Object、Array、Date、RegExp和Function等类型。它们具有以下特点和知识点: 1. Object类型是JavaScript中最为基础和常用的引用类型。它可以用来模拟现实世界中的对象模型,存储...
首先,`object`并不是JavaScript中的一个特定标识符或类型,而是`typeof`操作符在检测非原始类型(即非`undefined`、`boolean`、`number`、`string`、`function`、`symbol`)时返回的一个字符串值。这意味着,当你对...
JavaScript是一种广泛用于网页和网络应用的轻量级脚本语言,尤其在前端开发中起着核心作用。在理解和编写JavaScript代码时,...希望这些详细解释能帮你理清JavaScript数据类型的概念,让你在编写代码时更加得心应手。
本篇文章将深入解析JavaScript中的数据类型,并通过示例代码来进一步理解不同类型之间的转换。 #### 基础数据类型(Primitive Types) JavaScript中有六种基础数据类型: 1. **Undefined**:表示未定义的值。 2. ...
本篇将深入探讨JavaScript中的数据类型,包括基本数据类型、引用数据类型以及ES6引入的新的数据类型。 1. **基本数据类型** JavaScript中的基本数据类型包括: - **Undefined**:表示变量未定义或值不存在。 - *...
在 JavaScript 中有 5 种不同的可以包含值的数据类型: ● string ● number ● boolean ● object ● function 有 6 种类型的对象: ● Object ● Date ● Array ● String ● Number ● Boolean 以及 2 种不能包含...
在JavaScript中,Object和Function对象是两种非常基础且重要的数据类型。它们构成了JavaScript语言的核心机制,涉及到了对象的创建、继承以及函数的处理等方面。本文将深入探讨这两个对象及其相关特性。 1. Object...
Object 是 JavaScript 中的一种复杂数据类型,表示对象。Object 由一组无序的名值对组成。 例如: ```javascript var person = { name: "John", age: 25 }; alert(typeof person); // "object" ``` 在上面的例子中...
在JavaScript中,数据类型的转换是编程中不可或缺的一部分。在处理不同数据类型时,JavaScript会自动进行类型转换,以便于执行特定的操作。以下是关于JavaScript中数据类型转换的详细说明: 1. **原始数据类型转换*...
- **Object**:这是JavaScript中最复杂的数据类型,它可以是任何东西,包括数组、函数、日期等。对象实际上是键值对的集合,键是字符串,值可以是任意数据类型。 - **Array**:数组是特殊类型的对象,其键是数字,...
JavaScript语言核心数据类型和变量使用介绍的知识点包含在以下内容中。 首先,JavaScript的基础知识点中,变量是被赋予了值的符号名字,它作为存储数据的容器。变量可以通过var、let或const关键字进行声明。在上面...
在学习过传统的面向对象语言后,如 java c++,转学 javascript 却有点不适应,特别是 javascript 中所谓的 object(对象) function(函数),有时候会被搞晕。于是乎简单整理了下面的一些概念性的东西,方便学习和...
在JavaScript中,了解数据类型检测方法对于编写高效和健壮的代码至关重要。JavaScript是一种动态类型语言,这意味着变量的类型可以在运行时改变。因此,正确识别变量的数据类型是调试和优化代码的关键。 首先,我们...
在JavaScript中,一切皆为对象,包括基本数据类型,它们都有对应的包装对象。本文将深入探讨Object对象的使用和相关方法。 首先,Object对象可以用于创建新的对象实例。通过`new Object()`或直接使用大括号`{}`语法...
值得注意的是,JavaScript允许不同数据类型的变量在不同时间存储不同类型的数据,就像示例中的`name`从字符串变为数值。这种特性虽然灵活,但可能导致难以预测的行为,因此在实践中应尽量避免。 JavaScript还有五种...
1. **Object**:对象,JavaScript中最复杂的数据类型,可以包含任意类型的属性和方法。 - **Array**:数组,一种特殊类型的对象,用于存储有序的元素集合。 - **Function**:函数,也是对象,可以拥有属性和方法,...
在JavaScript中,`Function`和`Object`是两种基本的数据类型,它们之间的关系构成了JavaScript语言的核心特性。首先,根据描述,我们要明确一个关键点:在JavaScript中,所有的函数本质上都是对象,而`Function`和`...
JavaScript中的对象拷贝是编程中常见的操作,尤其在处理复杂数据结构时显得尤为重要。对象拷贝分为两种主要类型:浅拷贝和深拷贝。 浅拷贝是指创建一个新对象,新对象的属性引用了原对象中属性的引用。这意味着,当...