二. javascript面向对象的几个结论(new,prototype)
================================================================================================================
---------------------------------------------------------------
2.1 引子
---------------------------------------------------------------
因为javascript最初设计的面向对象存在缺陷,导致如果每一个对象关于"类的方法都进行一次硬拷贝"的问题:
function ShowText(text)
{
this.word = text;
this.sing = function singFunction() {alert("HelloWorld!~");};
}
obj1 = new ShowText("sb1");
obj2 = new ShowText("sb2");
这样的话obj1和obj2在内存中分别有一份singFunction的方法代码,显然这很sb,有两种改进方式:
) 外部定义函数对象,
function ShowText()
{
this.sing = singFunction;
}
function singFunction(){ alert("HelloWorld!~"); }
new ShowText().sing();
2) 利用函数对象的prototype属性
function ShowText()
{
}
ShowText.prototype.sing = function(){ alert( "HelloWorld!~");}
new ShowText().sing();
---------------------------------------------------------------
2.2 new关键字的作用
---------------------------------------------------------------
请对比如下的例子:
function ShowText(text)
{
this.word = text;
}
var obj = new ShowText("hi,tomsui!~");
alert(obj.word); // "hi,tomsui!~"
var obj2 = new Object();
obj2.constuct = ShowText;
obj2.constuct("hi,tomsui!~");
alert(obj2.word); // "hi,tomsui!~"
通过运行结果可以看出存在如下等价关系:
var ball0=new Ball("creating new Ball");
<==>
var ball0=new Object();
ball0.construct=Ball;
ball0.construct("creating new ball");
分析上述等价关系,可得到"new"关键字背后的实际动作如下:
a. 创建一个新的,空的object -- new Object()
b. 调用这个object的constructor;
obj.construct也是一个对象,对象都具备prototype属性,这是不必说的.
c. [补充] 拷贝这个object的construct的prototype属性到新生成的object中来(软拷贝引用)
说明: 1) "new"关键字让一个普通函数变为了构造器,可以把它理解为一种用于简化创建对象步骤的"约定"
2) 等价关系只能证明new的前两条作用,关于的prototype的叙述参见下边"2.3 prototype"
--------------------------------------------------------------
2.3 prototype
---------------------------------------------------------------
1. 首先注意:
1) prototype是函数对象才具备的属性,普通对象是没有的.
-- 我对一些sb书上说它是一切对象的属性(因为它是Object对象的属性)感到困惑
2) 构造函数prototype属性本身也是一个object,它具有如下特征:
a. 它存在一个constructor属性指向函数对象的代码 (死规定,记住就ok), 例如:
function showText(text) { alert(test);}
// 下面证明了showText的prototype属性是对象
alert(typeof(showText.prototype)); // object
// 下面说明了showText.prototype这个对象不能用默认toString()打印
alert(showText.prototype); // [object, Object]
// 下面证明showText.prototype.constructor的存在性
alert(showText.prototype.constructor); // function showText(text) { alert(test); }
alert(typeof showText.prototype.constructor); // function
b. 它像其他对象一样可以添加属性,例如:
// 添加属性text属性
function showText() {};
showText.prototype.text = "HelloWorld!~";
// 添加shout()方法
function showText() {}
showText.prototype.shout = function(){alert("tomsui wants to smoke!~");};
2. prototype的内幕
回想new关键字的幕后机制:
先用构造器生成一个对象, 然后"软拷贝构造器prototype属性的内容到新生成的object中来"。
下面,对引号中强调的内容有必要的两点解释:
1) "构造器prototype属性的内容"是什么?
构造器prototype属性是一个对象,那么它的内容包括两部分: a. 属性值 b. 方法
2) 什么是"软拷贝"?
就是仅仅拷贝内容的引用到新生成obj,并不是真正的prototype中的内容(软拷贝是tomsui借用linux中"ln -s"的说法,比较简洁吧~)
"软拷贝构造器prototype属性的内容到新生成的object中来"恐怕就是prototype的核心内幕了.
3. 引入prototype对javascript的影响
1) 为创建对象添加附加动作
为构造器的prototype新添加的任何"属性"和"方法",都会被new关键字在使用构造器创建对象时,附加到新的对象中去。
例如:
function ShowText() {};
// 添加text属性
ShowText.prototype.text = "HelloWorld!~";
alert(new ShowText().text); // HelloWorld!~
// 添加shout()方法
ShowText.prototype.shout = function(){alert("tomsui wants to smoke!~");};
new ShowText().shout(); // tomsui wants to smoke!~
上例中,构造器ShowText()本来可是没有text属性和shout()方法的哦~
2) prototype 不会影响到构造器的动作
所以如果两者发生矛盾时,构造器生效, -- 这非常值得注意!
例如:
function ShowText()
{
this.text = "tomsui is handsome!~";
this.say = function(){alert("absolutely!")};
}
ShowText.prototype.text = "J.J. is handsome!~";
ShowText.prototype.say = function(){alert("perhaps?")};
var obj = new ShowText();
alert(obj.text); // tomsui is handsome!~
obj.say(); // absolutely!
结果是: prototype界定的"J.J. is handsome!~"没有生效,(毕竟是伪科学么);
构造器讲出了"tomsui is handsome!~","absolutely!", 因为这是真理,不是prototype可以推翻的
3) prototype的出现,让js发生了所谓的"极晚绑定"。
晚绑定("后期绑定")可以参考TIJ或其他面向对象的书吧,不说了。
"极晚绑定"让javascript的伪面向对象更加变态:即便已经new出了一个对象实例,你仍然可以为其添加新的行为和属性,
例如:
function Person(name)
{
this.name = name;
this.wordsInHeart = "tell Rora I love her~";
}
var tts = new Person("tomsui"); // tell Rora I love her~
alert(tts.wordsInHeart);
Person.prototype.saySomeOtherWords = function(){alert("tell Rora I need her~")};
tts.saySomeOtherWords();
看见没有:
名为tomsui的Person对象出现时本来只会说"tell Rora I love her~",
但自从他学会了prototype招数,泡妞技术更上一层楼,
于是补充他又会多说: "tell Rora I need her~"。
这个例子可见"极晚绑定"的好处,有得有失,这种动作多了,你的js成本会很高(就是慢贝),所以谨慎使用。
ps.
I. "极晚绑定"是官方用语,可放心使用; 不像"软拷贝"这词这土。
II. 并不是完整介绍js的伪面向对象,仅作为js做抛砖引玉用。
转自:http://hi.baidu.com/flvu/blog/item/3a343e677a154c29ab184cbf.html
分享到:
相关推荐
### JavaScript面向对象编程精要 #### 一、引言 JavaScript是一种灵活且强大的脚本语言,它虽然起源于一种简单的浏览器脚本语言,但随着时间的发展,JavaScript已经成为了一种功能全面的编程语言,尤其是在Web开发...
在JavaScript中实现面向对象编程主要包括以下几个方面: - **类与对象**:JavaScript没有内置的类的概念,但在ES6中引入了`class`关键字来模拟类的行为。对象则是由类实例化出来的具体实体。 - **封装**:封装是指...
JavaScript的面向对象特性主要体现在以下几个方面: 1. **构造函数与原型**:函数在JavaScript中可以作为构造函数,通过`new`关键字创建新对象。构造函数的`prototype`属性允许对象共享方法和属性,实现继承。通过`...
在JavaScript中,面向对象主要依赖于以下几个关键概念: 1. **对象**:JavaScript的对象是由键值对组成的无序集合,这些键可以是字符串或符号,而值则可以是任意类型。对象是JavaScript的基础,它们可以通过字面量...
### JavaScript面向对象编程详解 #### 一、JavaScript与面向对象编程 JavaScript虽然是一种基于对象的语言,但其设计并不像传统的面向对象编程语言那样拥有明确的类(class)概念。这使得在JavaScript中实现面向...
### JavaScript面向对象之对象的深入理解 #### 一、引言 在JavaScript中,对象是其核心组成部分之一,几乎所有的操作都是围绕着对象来进行的。本文将深入探讨JavaScript中的对象概念,通过具体示例帮助读者更好地...
### JavaScript学习深入—面向对象编程 #### 一、JavaScript中的类型概述 JavaScript作为一种动态的、弱类型的语言,其核心特点之一在于它灵活的对象模型。尽管JavaScript的基础架构支持面向对象编程(OOP),但在...
以下是对标题和描述中提到的几种JavaScript面向对象编程模式的详细解释: 1. **构造函数与字面量结合模式** 在JavaScript中,我们可以通过构造函数和字面量语法来创建对象。构造函数用于定义对象的类型,而字面量...
总结一下,JavaScript面向对象编程主要包括类的表示(通过构造函数)、对象的创建(对象工厂、构造函数、原型模式)以及继承的实现(原型链)。理解这些概念对于深入学习JavaScript和开发复杂的JavaScript应用至关...
以上内容概述了 JavaScript 面向对象编程的基础概念及其在实际应用中的几种实现方式,并简要介绍了 CSS 样式的相关属性。面向对象编程是现代 Web 开发中不可或缺的一部分,掌握其核心概念对于提高开发效率和编写高...
### JavaScript面向对象编程入门与实践 #### 一、JavaScript中的对象与属性 在JavaScript中,对象是面向对象编程的核心组成部分。对象可以被视为包含属性和方法的数据集合。具体来说: - **属性**:对象的特征,...
### JavaScript 快速入门教程与面向对象编程 #### 一、概要 JavaScript 是一种广泛应用于网页开发中的脚本语言,具有轻量级、解释型等特点。它可以在客户端执行,无需服务器支持,使得网页能够更加动态和交互。 ##...
本文将探讨几种在JavaScript中声明和使用面向对象的方式。 首先,我们来看**工厂模式**。这是一种创建对象的模式,通过定义一个函数来创建具有特定属性和方法的对象。在工厂模式中,我们通常先定义一个基础结构,...
面向对象编程具有几个核心概念,包括封装(Encapsulation)、继承(Inheritance)和多态(Polymorphism): 1. 封装是指将数据(属性)和操作数据的方法(函数或方法)捆绑在一起,形成一个独立的单元——对象。...
ES6引入了类的概念,虽然它们在语法上类似于传统的面向对象语言,但本质上仍然是基于原型的。例如: ```javascript class PersonClass { constructor(name, age) { this.name = name; this.age = age; } ...
在面向对象的JavaScript编程中,有几个最佳实践可以帮助开发者编写更加健壮和可维护的代码: 1. **模块化**:将代码分割成独立的模块或库,每个模块负责一部分功能。 2. **命名空间**:为了避免全局命名冲突,可以...
这个过程涉及几个关键的内部操作,理解它们有助于更好地掌握JavaScript的原型继承和面向对象编程。 1. 创建一个空对象 当我们使用new关键字时,首先发生的是创建一个空对象。这个空对象是不包含任何属性和方法的新...