`
achun
  • 浏览: 306287 次
  • 性别: Icon_minigender_1
  • 来自: 河南郑州
社区版块
存档分类
最新评论

javascript的值,对象,原型

阅读更多

探讨一下,如有纰漏请指正.

认识在前面:先给出我们讨论的结果

===========================================

javascript是基于原型(prototype-based )的语言.

javascript具有面向对象(Object-Oriented )的编程风格.

变量不一定是对象(undefined,null等就是特例,但是NaN是个对象)

对象一定有值,也有成员(函数,属性)

Object不是顶级的,因为可以delete Object

顶级 的有:

Array Object
Boolean Object
Date Object
Function Object
Math Object
Number Object
RegExp Object
String Object

new 运算符具有一定的魔术性,这个说法我语言上还组织不好.

==========================================

首先我用了词:原型

马上您就知道为什么这么说了.

javascript是基于对象(Object-based )的吗?不是

javascript是面向对象(Object-Oriented )的吗? ,要清楚这句话指的是编程方法类似面向对象的编程,但是也有很多不同的地方.

那我们看看Mozilla官方的说法

写道
A prototype-based language, such as JavaScript, does not make this distinction: it simply has objects. A prototype-based language has the notion of a prototypical object, an object used as a template from which to get the initial properties for a new object. Any object can specify its own properties, either when you create it or at run time. In addition, any object can be associated as the prototype for another object, allowing the second object to share the first object's properties.

 javascript是基于原型(prototype-based )的语言.

 

那么我们在描述,研究这个语言的时候就会牵扯到这几个问题.

值和对象 :

var obj={};
var num=9;
var str='string'
var arr=[];

 很明显上面的几个变量都是一个对象,那变量一定是对象吗 ?

var foo;

 foo是一个变量,但是foo不是对象.对象有个事实上 的特征就是,对象一定有成员 (属性或方法).

 foo就没有任何成员,他的值是undefined ,而undefined 的定义是:

undefined is a property of the global object, i.e. it is a variable in global scope.
The initial value of undefined is the primitive value undefined.

undefined 属性是 Global 对象的一个成员,该属性在脚本引擎初始化后可用。如果已声明了一个变量但还没有初始化,那么该变量的值就是 undefined。

 也就是说undefined 是一个顶级共有属性,用关键字描述undefined 其实更确切.

 现在我们举几个值对象( javascript的其他类型的还有,就不提了)

'isstring'.constructor;//String()
true.constructor;//Boolean()
9.0.constructor;//Number();这下对了吧csf178
(9).constructor;//Number();匿名对象
9.constructor;//SyntaxError;经csf178指正,这是浮点数转换造成的语法冲突
[].constructor;//Array()
{}.constructor;//fireFox :SyntaxError;IE : Object();注意javascript定义中{}是代码块和对象定义,不是Operator
({}).constructor;//Object();匿名对象

 其实值对象这个说法不是很合适.就像上面的前3个确实是值.第4个(9)其实是一个匿名的Number对象 ,

但是接下来的两句就有意思了.{}和[]竟然还有如此的区别.而且fireFox和IE实现也不同.(其实从优先级上可以找到一些答案,可惜不同实现有差异)

Object Literals 中明确指出{}.xxx这种用法是错误的,所以fireFox出SyntaError是正常的.MS的jscript文档我没有看过,不知道如何解释这个.

那我们如何来评论javascript的这些特性呢?

抛弃面向对象这个说法吧,javascript真的不适合. javascript就是这样的不严格,但是很实用.

经csf178指正后,看来javascript仍旧是OO的.但是是prototype-based 的OO,不是Class-based的OO.

也就是说在javascript里所有的对象都有原型,官方给出的原型

(好在我写这个帖子的时候就是为了要搞清楚这3者的关系)

总结:变量不一定指向对象 (貌似废话),对象一定有值

原型 :

对象一定有原型constructor

这一点从可以从javascript的constructor的定义中找到根据.

请注意上面例子中所有的constructor都是以函数给出的,其实

原型constructor一定是一个函数形式的定义

javascript:function fun(){};
new fun.constructor;//anonymouse();
(new fun).constructor;//fun();
new fun().constructor;//fun();
(new fun()).constructor;//fun();

 为什么这样?其实这很正常,看看javascript运算符的优先级 就明白了.当然,你不能死照优先级来看语法的合法性,解释起来会很绕嘴的.

new Function().constructor;//Function()
new Function.constructor;//anonymous()
new (Function.constructor);//anonymous()
new (Function().constructor);//anonymous()

 这几个例子优先级就明显了.

(下面的几行是经csf178指正后,反思的结果)

回头再看看官方给出的原型 里面唯独却少了最重要的Object,我们知道Object一定是个对象(javascript里没有class),Object又不在Core里,那Object是从哪里来的呢?

Object().constructor;//Object()
Object.constructor;//Function()

原来Object是由系统自Function 创建的.怎么证明呢?

alert(Object);//Object()
delete Object;//true
Object;//ReferenceError: Object is not defined

但是你不能delete Function.

Function就是一切

(反思到这里了)

因此我们讨论javascript对象的时候不要用class-based OO 的概念去靠(经csf178指正),找原型 constructor 是关键

当然javascript提供了更直观的prototype 属性来实现OO方法的问题.

new 这个运算符具有一定的魔术性

function fun1(){this.n=3;}
function fun2(){this.n=3;return {};}
var foo1=new fun1;//{n:3}
var foo2=new fun2;//{}

 也就是说原型 constructor 的return值是对new有影响的.这就是new的魔术性

分享到:
评论
18 楼 csf177 2008-06-26  
ECMA对这个倒是没明确规定
但是按照ECMA262的意思 Object Function Array等并非GlobalObject的特权属性 所以应该都可以正确删除
所以虽然标准没有明确的规定 也不应该认为是implementation dependent的

FireFox在此处显然属于实现错误
因为alert(delete Function);是true

说实话 如果你读了SpiderMonkey源码 你会对它有很深的绝望
17 楼 achun 2008-06-26  
<p>还真的是实现有很大却别呀,<br/>Moz和IE的实现当中</p>
<pre name='code' class='js'>delete Object;
alert(typeof Object);
delete Function;
alert(typeof Function);</pre>
<p> 还真不一样.这个世界可真乱呀!</p>
<p> </p>
16 楼 csf177 2008-06-25  
<div class='quote_title'>achun 写道</div>
<div class='quote_div'>
<div class='quote_title'>soni 写道</div>
<div class='quote_div'>什么叫顶级的?是不是就是语言内建的叫顶级的?</div>
<p><br/>我也是这么理解的.不过还是用官方的说法比较合适.<br/><a href='http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Guide:Predefined_Core_Objects' target='_blank'>Predefined Core Objects</a></p>
<p>预定义核心对象,</p>
<p>问题是内建这个词没有一个定义,Object是系统一运行就建立的,算不算内建呢?</p>
<p>但是Objcet肯定不算Core Objects,因为官方列表中就没有.</p>
<p> </p>
</div>
<p>好像没什么区别吧 这些都可以delete</p>
<p>Moz写的文档只是把Object单拿出来说了</p>
<p> </p>
<p>不管怎么说ECMA现在比Moz更官方 ECMA现在是把它们放一起的</p>
15 楼 achun 2008-06-25  
<div class='quote_title'>soni 写道</div>
<div class='quote_div'>什么叫顶级的?是不是就是语言内建的叫顶级的?</div>
<p><br/>我也是这么理解的.不过还是用官方的说法比较合适.<br/><a href='http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Guide:Predefined_Core_Objects' target='_blank'>Predefined Core Objects</a></p>
<p>预定义核心对象,</p>
<p>问题是内建这个词没有一个定义,Object是系统一运行就建立的,算不算内建呢?</p>
<p>但是Objcet肯定不算Core Objects,因为官方列表中就没有.</p>
<p> </p>
14 楼 soni 2008-06-25  
什么叫顶级的?是不是就是语言内建的叫顶级的?
13 楼 achun 2008-06-25  
<div class='quote_title'>soni 写道</div>
<div class='quote_div'>lz想要说什么?</div>
<p>我想搞清楚几件事情,经过csf178的讨论,已经清楚了.就几句话.</p>
<p> </p>
<p>javascript是基于原型(<strong>prototype-based</strong>
)的语言.</p>
<p>javascript具有面向对象(<span style='color: #000000;'><strong>Object-Oriented</strong>
</span>
)的编程风格.</p>
<p><strong>变量不一定是对象(undefined,null等就是特例,但是NaN是个对象)</strong></p>
<p><strong>对象一定有值,也有成员(函数,属性)</strong></p>
<p><strong>Object不是顶级的,因为可以delete Object</strong></p>
<p><strong>顶级</strong>的有:</p>
<p style='background-color: #ffffff; padding-left: 30px;'> <strong><span style='color: #000000;'>Array Object<br/>Boolean Object<br/>Date Object<br/>Function Object<br/>Math Object<br/>Number Object<br/>RegExp Object<br/>String Object</span></strong></p>
<p><strong>new</strong>运算符具有一定的<strong>魔术性,这个说法我语言上还组织不好.</strong></p>
12 楼 soni 2008-06-25  
lz想要说什么?
11 楼 csf178 2008-06-21  
<div class='quote_title'>achun 写道</div>
<div class='quote_div'>
<div class='quote_title'>csf178 写道</div>
<div class='quote_div'>还有个小细节 其实<br/>alert({}.constructor);在FF里也是可以的<br/>{}.constructor;会有问题也是因为词法冲突 {}不在表达式中的时候会被认作语句块(而不是对象构造)<br/></div>
<p><br/><a href='http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Guide:Literals' target='_blank'>Object Literals</a> 中</p>
<div class='quote_title'>写道</div>
<div class='quote_div'>An object literal is a list of zero or more pairs of property names and associated values of an object, enclosed in curly braces ({}). You should not use an object literal <strong>at the beginning of a statement</strong>. This will lead to an error or not behave as you expect, because the { will be interpreted as the beginning of a block.</div>
<p> 明确了这种用法是会产生错误的.这种用法也就成了语法错误了,也就是你说的解析时候造成<strong>词法冲突</strong></p>
<p> </p>
</div>
<p>嗯 是这个意思</p>
<p>另外 其实constructor并不是很准 因为constructor可以被修改</p>
<p>在FF中 __proto__ 属性是原型链</p>
<p>var t={__proto__:{a:1,b:2},c:3}</p>
<p>alert(t.a);//1</p>
<p>alert(t.b);//2</p>
<p>alert(t.c);//3</p>
<p> </p>
<p>在JS中 new和函数的prototype可以看作是提供了一种用原型模拟类的方式 </p>
<p>把拥有同一个原型的一组对象看作属于一个类</p>
<p> </p>
10 楼 achun 2008-06-21  
<div class='quote_title'>csf178 写道</div>
<div class='quote_div'>还有个小细节 其实<br/>alert({}.constructor);在FF里也是可以的<br/>{}.constructor;会有问题也是因为词法冲突 {}不在表达式中的时候会被认作语句块(而不是对象构造)<br/></div>
<p><br/><a href='http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Guide:Literals' target='_blank'>Object Literals</a> 中</p>
<div class='quote_title'> 写道</div>
<div class='quote_div'>An object literal is a list of zero or more pairs of property names and associated values of an object, enclosed in curly braces ({}). You should not use an object literal <strong>at the beginning of a statement</strong>. This will lead to an error or not behave as you expect, because the { will be interpreted as the beginning of a block.</div>
<p> 明确了这种用法是会产生错误的.这种用法也就成了语法错误了,也就是你说的解析时候造成<strong>词法冲突</strong></p>
<p> </p>
9 楼 csf178 2008-06-21  
还有个小细节 其实
alert({}.constructor);在FF里也是可以的
{}.constructor;会有问题也是因为词法冲突 {}不在表达式中的时候会被认作语句块(而不是对象构造)

JS词法其实挺烦人的 {}这些还好 正则表达式的 / /语法跟除号的冲突 导致JS成为少数产生式不能完全描述词法的语言


顺便 我补充一点 关于new 可以从SpiderMonkey源码看看比普通的函数调用究竟多了什么
js_InvokeConstructor是new调用函数
js_Invoke就是普通的调用

下面代码第56到第59行是调用js_Invoke 其他部分就是new比普通函数多出来的部分
注释很清楚

JSBool
js_InvokeConstructor(JSContext *cx, jsval *vp, uintN argc)
{
    JSFunction *fun;
    JSObject *obj, *obj2, *proto, *parent;
    jsval lval, rval;
    JSClass *clasp, *funclasp;

    fun = NULL;
    obj2 = NULL;
    lval = *vp;
    if (!JSVAL_IS_OBJECT(lval) ||
        (obj2 = JSVAL_TO_OBJECT(lval)) == NULL ||
        /* XXX clean up to avoid special cases above ObjectOps layer */
        OBJ_GET_CLASS(cx, obj2) == &js_FunctionClass ||
        !obj2->map->ops->construct)
    {
        fun = js_ValueToFunction(cx, vp, JSV2F_CONSTRUCT);
        if (!fun)
            return JS_FALSE;
    }

    clasp = &js_ObjectClass;
    if (!obj2) {
        proto = parent = NULL;
        fun = NULL;
    } else {
        /*
         * Get the constructor prototype object for this function.
         * Use the nominal 'this' parameter slot, vp[1], as a local
         * root to protect this prototype, in case it has no other
         * strong refs.
         */
        if (!OBJ_GET_PROPERTY(cx, obj2,
                              ATOM_TO_JSID(cx->runtime->atomState
                                           .classPrototypeAtom),
                              &vp[1])) {
            return JS_FALSE;
        }
        rval = vp[1];
        proto = JSVAL_IS_OBJECT(rval) ? JSVAL_TO_OBJECT(rval) : NULL;
        parent = OBJ_GET_PARENT(cx, obj2);

        if (OBJ_GET_CLASS(cx, obj2) == &js_FunctionClass) {
            funclasp = ((JSFunction *)JS_GetPrivate(cx, obj2))->clasp;
            if (funclasp)
                clasp = funclasp;
        }
    }
    obj = js_NewObject(cx, clasp, proto, parent);
    if (!obj)
        return JS_FALSE;

    /* Now we have an object with a constructor method; call it. */
    vp[1] = OBJECT_TO_JSVAL(obj);
    if (!js_Invoke(cx, argc, JSINVOKE_CONSTRUCT)) {
        cx->weakRoots.newborn[GCX_OBJECT] = NULL;
        return JS_FALSE;
    }

    /* Check the return value and if it's primitive, force it to be obj. */
    rval = *vp;
    if (JSVAL_IS_PRIMITIVE(rval)) {
        if (!fun) {
            /* native [[Construct]] returning primitive is error */
            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
                                 JSMSG_BAD_NEW_RESULT,
                                 js_ValueToPrintableString(cx, rval));
            return JS_FALSE;
        }
        *vp = OBJECT_TO_JSVAL(obj);
    }

    JS_RUNTIME_METER(cx->runtime, constructs);
    return JS_TRUE;
}
8 楼 csf178 2008-06-20  
achun 写道
csf178 写道
achun 写道
果然有纰漏.
谢谢楼上两位.
同时修改了帖子,加入了一些反思的结果
引用
...Aiming的书吧...

偶E问太差,看不了呀!

Aiming的书是中文的啊

Aiming==周爱民


嘻嘻,都说了E文不好了.
Aiming也是E文表示的吧!
javascript的实体书只看过一本,Ajax and REST Recipes
还感觉对自己没有什么帮助(因为偶有自己完整的解决方案),所以就不再买了.
失误呀!


为啥我刚说到这本书就有看似枪文的东西出现......
http://www.iteye.com/topic/206407
7 楼 achun 2008-06-20  
csf178 写道
achun 写道
果然有纰漏.
谢谢楼上两位.
同时修改了帖子,加入了一些反思的结果
引用
...Aiming的书吧...

偶E问太差,看不了呀!

Aiming的书是中文的啊

Aiming==周爱民


嘻嘻,都说了E文不好了.
Aiming也是E文表示的吧!
javascript的实体书只看过一本,Ajax and REST Recipes
还感觉对自己没有什么帮助(因为偶有自己完整的解决方案),所以就不再买了.
失误呀!
6 楼 csf178 2008-06-20  
achun 写道
果然有纰漏.
谢谢楼上两位.
同时修改了帖子,加入了一些反思的结果
引用
...Aiming的书吧...

偶E问太差,看不了呀!

Aiming的书是中文的啊

Aiming==周爱民
5 楼 achun 2008-06-20  
果然有纰漏.
谢谢楼上两位.
同时修改了帖子,加入了一些反思的结果
引用
...Aiming的书吧...

偶E问太差,看不了呀!
4 楼 KKFC 2008-06-20  
说的好 刚搜索到早期的post:
《关于JavaScript的 貌似类(pseudo-classes)----不吐不快》
http://www.iteye.com/topic/85966
3 楼 csf178 2008-06-20  
去看Aiming的书吧 那本书比较靠谱
目前ECMA没有翻好的中文版
2 楼 csf178 2008-06-20  
prototype-based是OO的一种 wiki上说的很确切
js是OO的 ECMA-internal说的也很确切

9.constructor;//SyntaxError  
这个其实根对不对象没关系 纯粹是因为浮点数跟.运算的词法冲突

有些值类型可以.运算是因为.的时候默认转换成了对应的object

引用
我们讨论javascript对象的时候不要用OO的概念去靠


我觉得楼主思想很好 不过有些概念还是要注意一下 这样说比较合适:
引用
我们讨论javascript对象的时候不要用class-based OO的概念去靠

1 楼 KKFC 2008-06-20  
说得很精准确切,————收了

相关推荐

    JavaScript中的对象和原型(一)

     要了解面向对象,首先就要了解Javascript中的对象和原型。这篇文章中主要学习一下Javascript中的对象。  一 关于对象  对象其实就是一种引用类型。而对象的值就是引用类型的实例。在JavaScript 中引用类型是一...

    javascript原型和原型链

    2、所有的引用类型(数组、对象、函数)都有一个__proto__属性(隐式原型属性),属性值是一个普通的对象 console.log(array.__proto__); console.log(object.__proto__) console.log(func.__proto__) 3、所有的函数...

    深入理解JavaScript系列

    深入理解JavaScript系列(19):求值策略 深入理解JavaScript系列(20):《你真懂JavaScript吗?》答案详解 深入理解JavaScript系列(21):S.O.L.I.D五大原则之接口隔离原则ISP 深入理解JavaScript系列(22):...

    深入理解JavaScript系列(.chm)

    深入理解JavaScript系列(19):求值策略 深入理解JavaScript系列(20):《你真懂JavaScript吗 》答案详解 深入理解JavaScript系列(21):S O L I D五大原则之接口隔离原则ISP 深入理解JavaScript系列(22):S...

    javascript中对象的定义、使用以及对象和原型链操作小结

    本文实例总结了javascript中对象的定义、使用以及对象和原型链操作。分享给大家供大家参考,具体如下: 1. 除了5种基本类型外,JS中剩下的就是对象 (1)对象的定义: 直接定义: var test={x:1,y:1} new方式创建...

    深入理解JavaScript系列(42):设计模式之原型模式详解

    对于原型模式,我们可以利用JavaScript特有的原型继承特性去创建对象的方式,也就是创建的一个对象作为另外一个对象的prototype属性值。原型对象本身就是有效地利用了每个构造器创建的对象,例如,如果一个构造函数...

    源文件程序天下JAVASCRIPT实例自学手册

    4.5.4 通过原型为对象添加新属性和新方法 4.5.5 自定义对象的嵌套 4.5.6 内存的分配和释放 4.6 本章小结 第5章 文档对象模型(DOM) 5.1 DOM概述 5.1.1 基本对象模型 5.1.2 Netscape Navigator浏览器扩展 5.1.3 ...

    JavaScript详解(第2版)

    1.9.1 JavaScript对象 12 1.9.2 文档对象模型 12 1.10 关于浏览器 13 1.10.1 JavaScript的版本 14 1.10.2 你的浏览器遵循标准吗 16 1.10.3 浏览器是否已启用JavaScript 16 1.11 JavaScript代码放在哪儿...

    JavaScript中对象的不同创建方法

     javascript中的对象实际上就是一个由属性组成的关联数组,属性由名称和值组成,值的类型可以是任何数据类型,或者函数和其他对象。  创建一个简单对象: var foo = {}; foo.prop_1 = 'bar'; foo.prop_2 = ...

    javascript对象的创建和访问

    JavaScript,很少能让人想到它面向对象的特性,甚至有人说它不是面向对象的语言,因为它没有...JavaScript 中的对象实际上就是一个由属性组成的关联数组,属性由名称和值组成,值的类型可以是任何数据类型,或者函数和

    浅析JavaScript原型继承的陷阱

    JavaScript默认采用原型...持有对象的变量只是一个地址,而基本类型数据是值。当原型上存储对象时,就可能有一些陷阱。 先看第一个例子 代码如下:var create = function() { function Fn() {} return function(paren

    JavaScript权威指南(第6版)中文版pdf+源代码

     3.7 不可变的原始值和可变的对象引用47  3.8 类型转换48  3.9 变量声明55  3.10 变量作用域56  第4章 表达式和运算符60  4.1 原始表达式60  4.2 对象和数组的初始化表达式61  4.3 函数定义表达式62  4.4 ...

    JavaScript权威指南(第6版)

    3.7 不可变的原始值和可变的对象引用 3.8 类型转换 3.9 变量声明 3.10 变量作用域 第4章 表达式和运算符 4.1 原始表达式 4.2 对象和数组的初始化表达式 4.3 函数定义表达式 4.4 属性访问表达式 4.5 调用表达式 4.6 ...

    JavaScript权威指南(第6版)(附源码)

    3.7 不可变的原始值和可变的对象引用 3.8 类型转换 3.9 变量声明 3.10 变量作用域 第4章 表达式和运算符 4.1 原始表达式 4.2 对象和数组的初始化表达式 4.3 函数定义表达式 4.4 属性访问表达式 4.5 调用表达式 4.6 ...

    JavaScript模式中文[pdf] 百度云

     基本值类型包装器  错误对象  小结  第4章 函数  背景  回调模式  返回函数  自定义函数  即时函数  即时对象初始化  初始化时分支  函数属性——备忘模式  配置对象  Curry  小结  第5章 对象创建...

    JavaScript — 原型链与作用域链1

    i++) {// 块级作用域}作用域每次执行都会生成一个新的活动对象作用域内的所有变量自动成为活动对象中的属性只有在作用域执行时才解析活动对象内的属性值作用域每

    SmartClone:巧妙地克隆对象,包括其即时原型,无需担心!

    深度克隆JavaScript对象(包括其直接原型),而不会无意间从全局原型中复制方法和值。 还可以在新创建的对象中复制循环关系。 安装 npm install smartclone 用法 var smartClone = require ( "smartclone" ) ; var...

    理解JAVASCRIPT中hasOwnProperty()的作用

    JavaScript中hasOwnProperty函数方法是返回一个布尔值,指出一个对象是否具有指定名称的属性。 hasOwnProperty()使用方法: object.hasOwnProperty(proName)其中参数object是必选项。一个对象的实例。proName是必...

    JavaScript基础和实例代码

    4.5.4 通过原型为对象添加新属性和新方法 4.5.5 自定义对象的嵌套 4.5.6 内存的分配和释放 4.6 本章小结 第5章 文档对象模型(DOM) 5.1 DOM概述 5.1.1 基本对象模型 5.1.2 Netscape Navigator浏览器扩展 5.1.3 ...

    JavaScript 权威指南(第四版).pdf

     3.7 不可变的原始值和可变的对象引用47  3.8 类型转换48  3.9 变量声明55  3.10 变量作用域56  第4章 表达式和运算符60  4.1 原始表达式60  4.2 对象和数组的初始化表达式61  4.3 函数定义表达式62  4.4 ...

Global site tag (gtag.js) - Google Analytics