探讨一下,如有纰漏请指正.
首先我用了词:原型
马上您就知道为什么这么说了.
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的魔术性
分享到:
相关推荐
### JavaScript:对象与原型链教程 #### 一、概述 本教程旨在深入解析JavaScript中对象的概念及其核心机制——原型链。我们将从数据类型入手,逐步探索函数与作用域的细节,并重点讨论对象与属性的相关知识。 ###...
JavaScript中的原型对象、this的五种用法、原型继承以及Caller和Callee的使用是JavaScript编程中的核心概念。首先,让我们深入理解每个概念。 **原型对象(Prototype)** 在JavaScript中,每当定义一个函数,都会...
### JavaScript对象、原型、属性、构造函数、扩展、JSON #### JavaScript对象类型 JavaScript是一种广泛使用的脚本语言,尤其在Web开发中占据了重要的地位。它支持多种对象类型,包括内部对象、基于类的对象以及...
JavaScript通过原型链实现继承,即一个对象可以访问其原型对象的属性和方法。通过`__proto__`或`Object.getPrototypeOf`访问原型。 4. **原型式继承** 在没有类的情况下,JavaScript使用原型式继承模拟面向对象...
当试图访问一个对象的属性时,JavaScript会查找该对象自身,然后沿着原型链向上查找,直到找到该属性或到达原型链的顶端。 4. **原型对象的修改** 可以通过`__proto__`属性或`Object.getPrototypeOf`方法获取一个...
JavaScript原型和闭包是这门语言中两个比较难以理解且与其他面向对象语言区别较大的概念。理解这两个概念,不仅能让我们更深层次地理解JavaScript,而且有助于我们了解编程语言的设计思路,拓宽我们的视野。 首先,...
在JavaScript中,实例对象与原型对象是两种关键的概念,它们构成了JavaScript对象继承的基础。每当你创建一个新的对象实例,它都会有一个内部链接到它的构造函数的原型。这个原型对象包含了可以通过实例对象访问的...
JavaScript的继承机制基于原型,每个对象都有一个prototype属性,指向它的构造函数的原型对象。通过原型链,我们可以访问到对象的属性和方法,即使它们没有直接在当前对象上定义。 5. **作用域和闭包** ...
当读取对象的属性时,JavaScript首先在对象实例本身上查找,如果找到了,则直接返回该属性值。如果没有找到,它会继续沿着原型链向上查找,直到找到相应的属性或者到达原型链的末端。因此,对象的属性查找实际上是一...
总之,JavaScript的面向对象编程并不局限于传统的类和继承,而是通过对象、原型和函数等手段实现封装、继承和多态。理解并掌握JavaScript的面向对象特性,对于编写高效、可维护的Web应用程序至关重要。通过本系列...
总的来说,这份“即查即用-JavaScript核心对象参考手册”涵盖了JavaScript的基础到高级知识,包括核心对象、数据类型、控制流、函数、原型继承、事件处理、DOM操作以及异步编程。对初学者来说,这是一份非常全面且...
当尝试访问一个对象的属性时,如果该对象本身没有定义该属性,则JavaScript引擎会沿着该对象的原型链向上查找,直至找到该属性为止。 每个JavaScript对象都有一个内部属性`[[Prototype]]`,指向另一个对象。当创建...
在了解JavaScript对象原型链原理之前,我们需要先理解JavaScript中的对象、原型以及原型链的基本概念。 JavaScript中的对象是一种复合值,它将许多值(原始值或其他对象)聚合在一起,可以通过名称访问这些值。对象...
5. **组合和模拟类**:由于JavaScript没有内置的类概念,开发者通常使用构造函数和原型模拟类的行为,通过`call`和`apply`方法实现方法的共享,通过`Object.create`创建基于特定原型的新对象。 6. **模块和封装**:...
JavaScript中的原型链机制允许对象继承原型对象的属性和方法,实现一种基于原型的继承。 JavaScript还提供了特殊的方法来枚举对象的属性,如for...in循环,它允许遍历对象中所有的可枚举属性,包括那些通过原型链...
本文将深入探讨JavaScript面向对象的关键概念,包括构造函数、原型链、继承以及作用域等。 #### 构造函数与实例化 构造函数是用于创建特定类型对象的函数。通过使用`new`关键字,我们可以基于构造函数创建对象实例...
而在JavaScript中,对象更像是一个包含键/值对的字典,通过`.`或`[]`运算符来访问或修改对象的属性和方法。例如: ```javascript // 创建一个空对象 var obj = new Object(); // 设置一个日期属性 obj.Now = new ...
1. **基于对象**:JavaScript中的所有数据都是对象,无论是基本类型如数字、字符串、布尔值,还是更复杂的自定义对象。这种基于对象的特性使得JavaScript具备了丰富的数据处理能力。 2. **封装**:通过函数和作用域...
在JavaScript中,原型继承是一种非常核心且独特的机制,它使得对象能够继承其他对象的属性和方法。本文旨在深入探讨这一机制,并通过具体的示例代码帮助读者更好地理解其中的概念。 #### 二、基本概念 在JavaScript...