- 浏览: 3319272 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (567)
- Web前端-html/表单 (19)
- Web前端-CSS (24)
- Web前端-CSS框架 (4)
- Web前端-JS语言核心 (50)
- Web前端-JS客户端 (26)
- nodejs生态+grunt (10)
- seajs和requirejs (9)
- backbone等框架 (7)
- 模板基础 (7)
- Web前端-deps(不改动) (6)
- Web前端-component (10)
- Web前端-jquery-plugin (13)
- 浏览器兼容性 (6)
- Web前端-使用jQuery (25)
- Web前端-使用jqueryui (6)
- Web前端-性能优化 (3)
- Web协议-HTTP (6)
- ExtJS (13)
- PHP (22)
- PHP面向对象 (4)
- PHP扩展-SOAP (6)
- PHP扩展-curl (4)
- PHP与HTML(导出) (5)
- PHP扩展-综合 (7)
- mysql基础应用 (18)
- 技术心情 (18)
- 算法和面试题 (17)
- 工具(开发)使用 (36)
- memcached原理 (2)
- session和cookie (4)
- UML (2)
- Web前端_FusionCharts (5)
- Web前端_Flex (4)
- Web前端_JSP (3)
- JavaSE (10)
- JavaEE (4)
- tomcat (2)
- Servlet开发 (3)
- Spring开发 (1)
- REST相关 (2)
- 大访问量、高并发 (2)
- 网络编程 (1)
- YII (21)
- linux命令和内核 (12)
- yii与数据库 (10)
- yii与表单 (12)
- yii view层 (1)
- perl (7)
- yii扩展 (7)
- shell (4)
- photoshop (7)
- 视觉设计 (2)
- 我关注的名人在路上 (4)
- 1-自学能力 (1)
- 2-人际沟通能力 (3)
- 3-职业规划能力 (7)
- 4-项目管理能力 (2)
- python (3)
- django (4)
- Mysql高级应用 (6)
- prototype.js (4)
- Web系统安全 (1)
- Web前端-mobile (2)
- egret (6)
- jQuery源码分析 (5)
- fis (4)
最新评论
-
yzq21056563:
感谢作者分享~请教下,http://www.lisa33xia ...
CSS基础:text-overflow:ellipsis溢出文本 -
u012206458:
$.ajax的error,complete,success方法 -
DEMONU:
谢谢,虽然不能给你赞助,但是要给你顶
mysql中key 、primary key 、unique key 与index区别 -
njupt_tolmes:
阿凡达阿凡达阿凡达阿凡达阿凡达阿凡达阿凡达阿凡达阿凡达阿滕庆亚 ...
CSS基础:text-overflow:ellipsis溢出文本 -
zenmshuo:
用过SpreadJS,也包含数据可视化的图表
推荐几个web中常用js图表插件
作者:zccst
三、原型模式
每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特点类型的所有实例共享的属性和方法。换言之,prototype就是通过调用构造函数而创建的那个对象实例的原型对象。
例如:
此时构造函数是空函数,即使如此,也仍然可以通过调用构造函数来创建新对象,而且新对象还会具有相同的属性和方法。但与构造函数模式不同的是,新对象的这些属性和方法是由所有实例共享的。换句话,p1和p2访问的都是同一组属性和同一个sayName()函数。
要理解原型模式的工作原理,必须先理解ECMAScript中原型对象的性质。
1,理解原型对象
无论什么时候,只要创建了一个新函数,就会根据一组特定的规则为该函数创建了一个prototype属性,这个属性指向函数的原型对象。在默认情况下,所有原型对象都会自动获得一个constructor(构造函数)属性,这个属性包含一个指向prototype属性所在函数的指针。
创建了自定义的构造函数之后,其原型对象默认只会取得constructor属性;至于其他方法,则都是从Object继承而来的。当调用构造函数创建一个新实例后,该实例的内部将包含一个指针(内部属性),指向构造函数的原型对象。(__proto__,不是所有浏览器都可见)。不过要明确真正重要的一点,是这个连接存在于实例与构造函数的原型对象之间,而不是实例与构造函数之间。
虽然某些实现中无法访问到内部的__proto__属性,但在所有的实现中都可以通过isPrototypeof()方法来确定对象之间是否存在这种关系。从本质上讲,如果对象的__proto__指向调用isPrototypeof()方法的对象,那么这个方法就返回true,如下所示:
每当代码读取某个对象的属性时,都会执行一次搜索,先从对象实例本身开始。如果实例中找到了具有给定名字的属性,则返回该属性的值;如果没有找到,则继续搜索指针指向的原型对象,在原型对象中查找具有给定名字的属性。如果在原型对象中找到了这个属性,则返回该属性的值。当调用p2.sayName()时,将会重现相同的搜索过程,得到相同的结果。而这正是多个对象实例共享原型所保存的属性和方法的基本原理。
备注:原型最初只包含constructor属性,而该属性也是共享的,因此可以通过对象实例访问。
虽然通过对象实例访问保存在原型中的值,但却不能通过对象实例重写原型中的值。如果我们在实例中添加了一个属性,二该属性与实例原型中的一个属性同名,那我们就在实例中创建该属性,该属性将会屏蔽原型中的那个属性。
当为对象实例添加一个属性时,这个属性就会屏蔽原型对象中保存的同名属性;换句话说,添加这个属性只会阻止我们访问原型中的那个属性,但不会修改那个属性。即使将这个属性设置为null,也只会在实例中设置这个属性,而不会恢复其指向原型的连接。不过使用delete操作符则可以完全删除实例属性,从而让我们能够重新访问原型中的属性,如下所示:
使用hasOwnProperty()方法可以检测一个属性是存在与实例中,还是存在于原型中。这个方法(不要忘记他是从Object继承来的)只在给定属性存在于对象实例中,才会返回true。
2,原型与in操作符
在以上代码执行过程中,name属性要么是直接在对象上访问到的,要么是通过原型访问到的。因此,调用"name" in p1始终都返回true,无论该属性存在于实例中还是存在于原型中。同时使用hasOwnProperty()和in操作符,就可以确定该属性到底是存在于对象中,还是存在于原型中,如下所示:
使用for-in循环时,返回的是所有能够通过对象访问的,可枚举的属性,其中既包括存在于实例中的属性,也包括存在于原型中的属性。
批注:
可枚举的属性
不可枚举的属性
3,更简单的原型语法
前面例子每添加一个属性和方法就要敲一遍Person.prototype。为减少不必要的输入,也为了从视觉上更好地封装原型的功能,更常见的做法是用一个包含所有属性和方法的对象字面量来重新整个原型对象,如下面的例子所示:
在上面的代码中,我们将Person.prototype设置为等于一个对象字面量形式创建的新对象,最终结果相同,但有一个例外:constructor属性不再指向Person了。前面曾经介绍过,每创建一个函数,就会同时创建它的prototype对象,这个对象也会自动获得constructor属性。而我们在这里使用的语法,本质上完全重写了默认的prototype对象,因此constructor属性也就变成了新对象的constructor属性(指向Object构造函数),不再指向Person函数。此时,尽管instanceof操作符还能返回正确的结果,但通过constructor已经无法确定对象的类型了,如下所示:
如果constructor真的很重要,可以像下面这样特意将他设置回适当的值:
备注:实例的constructor属性与原型对象的constructor属性是指的同一个内容吗?
推理可以得出,应该是指向同一个内容,那就是Person对象自身。
4,原型的动态性
由于在原型中查找值的过程是一次搜索,因此我们对原型对象所做的任何修改都能够立即从实例上反映出来——即使是先创建了实例后修改原型也照样如此。
即使p实例是在添加新方法之前创建的,但它仍然可以访问这个新方法。其原因可以归结为实例与原型之间松散的连接关系。对我们调用person.sayHi()时,首先会在实例中搜索名为sayHi的属性,在没找到的情况下,会继续搜索原型。因为实例与原型之间的连接只不过是一个指针,而非一个副本,因此就可以在原型中找到新的sayHi属性并返回保存在哪里的函数。
尽管可以随时为原型添加属性和方法,并且修改能够立即在所有对象实例中反映出来,但如果是重写整个原型对象,那么情况就不一样了。我们知道,调用构造函数时会为实例添加一个指向最初原型的__proto__指针,而把原型修改为另外一个对象就等于切断了构造函数与最初原型之间的联系。请记住:实例中的指针仅指向原型,而不是指向构造函数。
这个例子中,先创建了Person的一个实例,然后又重写了其原型对象。然后在调用p.sayName()时发生了错误,因为p指向的原型中不包含以改名字命名的属性。如图展示了这个过程的内幕:
从图中可以看出,重写原型对象切断了现有原型与任何之前已经存在的对象实例之间的联系;他们引用的仍然是最初的原型。
5,原生对象的原型
原型对象的重要性不仅体现在创建自定义类型方面,就连所有原生的引用类型,都是采用这种模式创建的。所有原生引用类型(Object,Array,String等)都在其构造函数的原型上定义了方法。例如,在Array.prototype中可以找到sort方法,而在String.prototype中可以找到substring()方法,如下所示:
alert(typeof Array.prototype.sort); // function
alert(typeof String.prototype.substring); // function
通过原生对象的原型,不仅可以取得所有默认方法的引用,而且也可以定义新方法。可以像修改自定义对象的原型一样修改原生对象的原型,因此可以随时添加方法。下面的代码就给基本包装类型String添加了一个名为startsWith()的方法:
String.prototype.startsWith = function(text){
return this.indexOf(text) == 0;
};
var msg = "hello world";
msg.startsWith("hello"); // true
提示:不推荐在产品化的程序中修改原生对象的原型。原因是:在另一个支持该方法的实现中运行代码时,就可能会导致命名冲突。而且这样做有可能会意外地重写原生方法。
6,原型对象的问题
原型模式也不是没有缺点。首先,它省略了为购置还是传递初始化参数这一环节,结果所有实例在默认情况下都将取得相同的属性值。虽然这会在某种程度上带来一些不方便,但还不是原型的最大问题。原型模式的最大问题是由其共享的本性所导致的。
原型中所有属性是被很多实例共享的,这种共享对于还是非常合适。对于那些包含基本值的属性倒也说得过去,毕竟通过在实例上添加一个同名属性,可以隐藏原型中的对应属性。然而对于包含引用类型的属性来说,问题就比较突出了,看下面的例子:
假如我们的初衷就像这样在所有实例中共享一个数组,那么对这个结果我没有话可说。可是,实例一般都是要有属于自己的全部属性。而这个问题正是我们很少看到有人单独使用原型模式的原因所在。
//两个方法
//hasOwnProperty()
//hasPrototypeProperty()
//覆盖原则
//方式二:字面量写法
Person.prototype = {
name : "nick",
age : 26,
job : 'design',
sayName : function(){
alert(this.name);
}
};
var p1 = new Person();//后定义对象
var p2 = new Person();
//p1.sayName();
//alert(p1.sayName() == p2.sayName());
//console.log(p1.__proto__);//Object { name="nick", age=26, job="design"}
//console.log(p1);//Object { name="nick", age=26, job="design"}
//alert(Person.prototype.isPrototypeOf(p1));//true
//alert(Person.prototype.isPrototypeOf(p2));//true
//尽管instanceof可以返回正确的结果。
//对比先定义对象与后定义对象的区别
console.log(person);//Person {}
console.log(person.constructor);//Person()
alert(person.constructor == Person); //true
alert(person.constructor == Object); //false
console.log(p1);//Object { name="nick", age=26, job="design"}
console.log(p1.constructor);//Object()
alert(p1.constructor == Person);//false 本质是完全重写了默认的原型对象(prototype)。因此constructor属性也就变成了新对象的constructor属性(指向Object构造函数),不再指向Person函数。可以通过constructor : Person设回正确的值。
alert(p1.constructor == Object);//true
三、原型模式
每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特点类型的所有实例共享的属性和方法。换言之,prototype就是通过调用构造函数而创建的那个对象实例的原型对象。
例如:
function Person(){} Person.prototype.name = "nick"; Person.prototype.age = 26; Person.prototype.job = 'design'; Person.prototype.sayName = function(){alert(this.name);} var p1 = new Person(); p1.sayName();//nick var p2 = new Person(); p2.sayName();//nick alert(p1.sayName == p2.sayName); //true
此时构造函数是空函数,即使如此,也仍然可以通过调用构造函数来创建新对象,而且新对象还会具有相同的属性和方法。但与构造函数模式不同的是,新对象的这些属性和方法是由所有实例共享的。换句话,p1和p2访问的都是同一组属性和同一个sayName()函数。
要理解原型模式的工作原理,必须先理解ECMAScript中原型对象的性质。
1,理解原型对象
无论什么时候,只要创建了一个新函数,就会根据一组特定的规则为该函数创建了一个prototype属性,这个属性指向函数的原型对象。在默认情况下,所有原型对象都会自动获得一个constructor(构造函数)属性,这个属性包含一个指向prototype属性所在函数的指针。
创建了自定义的构造函数之后,其原型对象默认只会取得constructor属性;至于其他方法,则都是从Object继承而来的。当调用构造函数创建一个新实例后,该实例的内部将包含一个指针(内部属性),指向构造函数的原型对象。(__proto__,不是所有浏览器都可见)。不过要明确真正重要的一点,是这个连接存在于实例与构造函数的原型对象之间,而不是实例与构造函数之间。
虽然某些实现中无法访问到内部的__proto__属性,但在所有的实现中都可以通过isPrototypeof()方法来确定对象之间是否存在这种关系。从本质上讲,如果对象的__proto__指向调用isPrototypeof()方法的对象,那么这个方法就返回true,如下所示:
alert(Person.prototype.isPrototypeof(p1)); //true alert(Person.prototype.isPrototypeof(p2)); //true
每当代码读取某个对象的属性时,都会执行一次搜索,先从对象实例本身开始。如果实例中找到了具有给定名字的属性,则返回该属性的值;如果没有找到,则继续搜索指针指向的原型对象,在原型对象中查找具有给定名字的属性。如果在原型对象中找到了这个属性,则返回该属性的值。当调用p2.sayName()时,将会重现相同的搜索过程,得到相同的结果。而这正是多个对象实例共享原型所保存的属性和方法的基本原理。
备注:原型最初只包含constructor属性,而该属性也是共享的,因此可以通过对象实例访问。
虽然通过对象实例访问保存在原型中的值,但却不能通过对象实例重写原型中的值。如果我们在实例中添加了一个属性,二该属性与实例原型中的一个属性同名,那我们就在实例中创建该属性,该属性将会屏蔽原型中的那个属性。
当为对象实例添加一个属性时,这个属性就会屏蔽原型对象中保存的同名属性;换句话说,添加这个属性只会阻止我们访问原型中的那个属性,但不会修改那个属性。即使将这个属性设置为null,也只会在实例中设置这个属性,而不会恢复其指向原型的连接。不过使用delete操作符则可以完全删除实例属性,从而让我们能够重新访问原型中的属性,如下所示:
function Person(){} Person.prototype.name = "nick"; Person.prototype.age = 26; Person.prototype.job = 'design'; Person.prototype.sayName = function(){alert(this.name);} var p1 = new Person(); var p2 = new Person(); p1.name = "Greg"; alert(p1.name); // Greg 来自实例 alert(p2.name); // nick 来自原型 //重点是这里 delete p1.name; alert(p1.name); // nick 来自原型
使用hasOwnProperty()方法可以检测一个属性是存在与实例中,还是存在于原型中。这个方法(不要忘记他是从Object继承来的)只在给定属性存在于对象实例中,才会返回true。
alert(p1.hasOwnProperty("name"); // false p1.name = "Greg"; alert(p1.name);//Greg 来自实例 alert(p1.hasOwnProperty("name"); // true alert(p2.name);//nick 来自原型 alert(p2.hasOwnProperty("name"); // false delete p1.name; alert(p1.name);//nick 来自原型 alert(p1.hasOwnProperty("name"); // false
2,原型与in操作符
alert(p1.hasOwnProperty("name"); // false alert("name" in p1); //true p1.name = "Greg"; alert(p1.name);//Greg 来自实例 alert(p1.hasOwnProperty("name"); // true alert("name" in p1); //true alert(p2.name);//nick 来自原型 alert(p2.hasOwnProperty("name"); // false alert("name" in p2); //true delete p1.name; alert(p1.name);//nick 来自原型 alert(p1.hasOwnProperty("name"); // false alert("name" in p1); //true
在以上代码执行过程中,name属性要么是直接在对象上访问到的,要么是通过原型访问到的。因此,调用"name" in p1始终都返回true,无论该属性存在于实例中还是存在于原型中。同时使用hasOwnProperty()和in操作符,就可以确定该属性到底是存在于对象中,还是存在于原型中,如下所示:
function hasPrototypeProperty(object ,name){ return !object.hasOwnProperty("name") && (name in object); }
使用for-in循环时,返回的是所有能够通过对象访问的,可枚举的属性,其中既包括存在于实例中的属性,也包括存在于原型中的属性。
批注:
可枚举的属性
不可枚举的属性
3,更简单的原型语法
前面例子每添加一个属性和方法就要敲一遍Person.prototype。为减少不必要的输入,也为了从视觉上更好地封装原型的功能,更常见的做法是用一个包含所有属性和方法的对象字面量来重新整个原型对象,如下面的例子所示:
function Person(){ } Person.prototype = { name:"Nicholas", age : 29, job : "Software Engineer", sayName : function(){ alert(this.name); } };
在上面的代码中,我们将Person.prototype设置为等于一个对象字面量形式创建的新对象,最终结果相同,但有一个例外:constructor属性不再指向Person了。前面曾经介绍过,每创建一个函数,就会同时创建它的prototype对象,这个对象也会自动获得constructor属性。而我们在这里使用的语法,本质上完全重写了默认的prototype对象,因此constructor属性也就变成了新对象的constructor属性(指向Object构造函数),不再指向Person函数。此时,尽管instanceof操作符还能返回正确的结果,但通过constructor已经无法确定对象的类型了,如下所示:
var p = new Person(); alert(p instanceof Person); alert(p instanceof Object); alert(p.constructor == Person); //false alert(p.constructor == Object); //true
如果constructor真的很重要,可以像下面这样特意将他设置回适当的值:
function Person(){ } Person.prototype = { constructor:Person,//特意包含了一个constructor属性,并将它的值设置为Person,从而确保通过该属性能够访问到适当的值 name:"Nicholas", age : 29, job : "Software Engineer", sayName : function(){ alert(this.name); } };
var p = new Person(); alert(p instanceof Person); alert(p instanceof Object); alert(p.constructor == Person); //false alert(p.constructor == Object); //true
备注:实例的constructor属性与原型对象的constructor属性是指的同一个内容吗?
推理可以得出,应该是指向同一个内容,那就是Person对象自身。
4,原型的动态性
由于在原型中查找值的过程是一次搜索,因此我们对原型对象所做的任何修改都能够立即从实例上反映出来——即使是先创建了实例后修改原型也照样如此。
var p = new Person(); Person.prototype.sayName = function(){ alert("hi"); } p.sayName();//"hi"
即使p实例是在添加新方法之前创建的,但它仍然可以访问这个新方法。其原因可以归结为实例与原型之间松散的连接关系。对我们调用person.sayHi()时,首先会在实例中搜索名为sayHi的属性,在没找到的情况下,会继续搜索原型。因为实例与原型之间的连接只不过是一个指针,而非一个副本,因此就可以在原型中找到新的sayHi属性并返回保存在哪里的函数。
尽管可以随时为原型添加属性和方法,并且修改能够立即在所有对象实例中反映出来,但如果是重写整个原型对象,那么情况就不一样了。我们知道,调用构造函数时会为实例添加一个指向最初原型的__proto__指针,而把原型修改为另外一个对象就等于切断了构造函数与最初原型之间的联系。请记住:实例中的指针仅指向原型,而不是指向构造函数。
function Person(){} var p = new Person(); Person.prototype = { constructor:Person, name:"Nicholas", age : 29, job : "Software Engineer", sayName : function(){ alert(this.name); } }; p.sayName(); //error
这个例子中,先创建了Person的一个实例,然后又重写了其原型对象。然后在调用p.sayName()时发生了错误,因为p指向的原型中不包含以改名字命名的属性。如图展示了这个过程的内幕:
从图中可以看出,重写原型对象切断了现有原型与任何之前已经存在的对象实例之间的联系;他们引用的仍然是最初的原型。
5,原生对象的原型
原型对象的重要性不仅体现在创建自定义类型方面,就连所有原生的引用类型,都是采用这种模式创建的。所有原生引用类型(Object,Array,String等)都在其构造函数的原型上定义了方法。例如,在Array.prototype中可以找到sort方法,而在String.prototype中可以找到substring()方法,如下所示:
alert(typeof Array.prototype.sort); // function
alert(typeof String.prototype.substring); // function
通过原生对象的原型,不仅可以取得所有默认方法的引用,而且也可以定义新方法。可以像修改自定义对象的原型一样修改原生对象的原型,因此可以随时添加方法。下面的代码就给基本包装类型String添加了一个名为startsWith()的方法:
String.prototype.startsWith = function(text){
return this.indexOf(text) == 0;
};
var msg = "hello world";
msg.startsWith("hello"); // true
提示:不推荐在产品化的程序中修改原生对象的原型。原因是:在另一个支持该方法的实现中运行代码时,就可能会导致命名冲突。而且这样做有可能会意外地重写原生方法。
6,原型对象的问题
原型模式也不是没有缺点。首先,它省略了为购置还是传递初始化参数这一环节,结果所有实例在默认情况下都将取得相同的属性值。虽然这会在某种程度上带来一些不方便,但还不是原型的最大问题。原型模式的最大问题是由其共享的本性所导致的。
原型中所有属性是被很多实例共享的,这种共享对于还是非常合适。对于那些包含基本值的属性倒也说得过去,毕竟通过在实例上添加一个同名属性,可以隐藏原型中的对应属性。然而对于包含引用类型的属性来说,问题就比较突出了,看下面的例子:
function Person(){ } Person.prototype = { constructor:Person, name:"Nicholas", age:29, job:"Software Engineer", friends:["Shelby","Court"], sayName:function(){ alert(this.name); } } var p1 = new Person(); var p2 = new Person(); p1.friends.push("Van"); alert(p1.friends); // "Shelby, Court, Van" alert(p2.friends); // 【重要】"Shelby, Court, Van" alert(p1.friends == p2.friends); // true
假如我们的初衷就像这样在所有实例中共享一个数组,那么对这个结果我没有话可说。可是,实例一般都是要有属于自己的全部属性。而这个问题正是我们很少看到有人单独使用原型模式的原因所在。
//两个方法
//hasOwnProperty()
//hasPrototypeProperty()
//覆盖原则
//方式二:字面量写法
Person.prototype = {
name : "nick",
age : 26,
job : 'design',
sayName : function(){
alert(this.name);
}
};
var p1 = new Person();//后定义对象
var p2 = new Person();
//p1.sayName();
//alert(p1.sayName() == p2.sayName());
//console.log(p1.__proto__);//Object { name="nick", age=26, job="design"}
//console.log(p1);//Object { name="nick", age=26, job="design"}
//alert(Person.prototype.isPrototypeOf(p1));//true
//alert(Person.prototype.isPrototypeOf(p2));//true
//尽管instanceof可以返回正确的结果。
//对比先定义对象与后定义对象的区别
console.log(person);//Person {}
console.log(person.constructor);//Person()
alert(person.constructor == Person); //true
alert(person.constructor == Object); //false
console.log(p1);//Object { name="nick", age=26, job="design"}
console.log(p1.constructor);//Object()
alert(p1.constructor == Person);//false 本质是完全重写了默认的原型对象(prototype)。因此constructor属性也就变成了新对象的constructor属性(指向Object构造函数),不再指向Person函数。可以通过constructor : Person设回正确的值。
alert(p1.constructor == Object);//true
发表评论
-
[正则]改变URL中的参数值
2015-05-20 20:37 4420作者:zccst 如果一个URL是:http://www.e ... -
理解JavaScript的单线程运行机制及setTimeout(fn,0)
2015-03-30 17:56 5601zccst整理 阮老师的链接 ... -
延迟自定义函数
2015-03-26 14:02 1061作者:zccst 如果函数内又定义了一个跟自己同名的函数,执 ... -
js语句和表达式
2015-03-11 11:21 712作者:zccst 一直觉得语句和表达式很简单,不需要专门留意 ... -
再次学习try catch finally
2015-03-10 11:26 1790作者:zccst 一、基本介绍 JavaScript的错误 ... -
[201502]封装
2015-02-07 11:59 813作者:zccst 我理解的封装是建立在熟悉面向对象和继承的基 ... -
js运算符优先级
2015-01-26 10:39 2624作者:zccst js运算符优先级也是一个巨大的坑。有时候你 ... -
《JavaScript模式》读书笔记
2015-01-23 11:59 890作者:zccst 第四章:函 ... -
js判断复合数据类型的两种方式(typeof不奏效了)
2014-11-07 17:47 2516作者:zccst typeof认为所有的复合数据类型都是&q ... -
js-闭包(权威指南版)
2014-10-27 18:42 1393作者:zccst //1,闭包是 ... -
js数据类型转换
2014-10-22 10:53 6670作者:zccst 2015-3-27 类 ... -
html5的onhashchange和history历史管理
2014-09-20 08:18 4761作者:zccst 现在的开发,越来越倾向于页面内跳转,这种情 ... -
Javascript语言精粹-毒瘤和糟粕
2014-09-16 18:37 1212作者:zccst Javascript是一门语言,用久了肯定能 ... -
[夏天Object]运行时程序执行的上下文堆栈(一)
2014-07-01 22:26 1571作者:zccst 时间:2014-07-01 这已经是第二 ... -
[Object]继承(经典版)(五)封装
2014-06-18 22:21 1136作者:zccst 封装已经上升到写插件的水平了,与多重继承属 ... -
[Object]继承(经典版)(四)多重继承和组合继承
2014-06-18 22:16 1587作者:zccst 一、多重继承 不得不说,这又是异常精彩的 ... -
[Object]继承(经典版)(三)继承理论总结
2014-06-18 22:15 1269作者:zccst 更新:在JavaScript模式中,作者 ... -
[Object]继承(经典版)(二)原型链(原型继承)
2014-06-18 22:05 1083作者:zccst 毫不夸张的说,这节是继承的核心所在。是重中 ... -
[Object]继承(经典版)(一)对象冒充和Call
2014-06-18 21:51 2552作者:zccst 先臆想一下这种方法 var a = ... -
[Object]面向对象编程(高程版)(0)属性和方法
2014-06-16 23:04 967zccst转载+原创 function Person() ...
相关推荐
面向对象编程(Object-Oriented Programming,OOP)是编程的一种重要范式,JavaScript也完全支持这一特性,尽管它并非一种传统的静态类型语言。这篇博客文章可能详细讨论了如何在JavaScript中实现面向对象编程。 在...
面向对象编程(Object-Oriented Programming,OOP)是JavaScript中的一个重要概念,它允许开发者通过对象来组织代码,提高可读性和可维护性。本指南的第二版深入探讨了JavaScript的面向对象特性,旨在帮助开发者更好...
面向对象编程(Object-Oriented Programming,简称OOP)是一种编程范式,它基于“对象”的概念,将数据和操作这些数据的方法封装在一起。在Python中,面向对象编程是其核心特性之一,使得Python成为了一种非常适合...
在JavaScript中,面向对象编程(Object-Oriented Programming,简称OOP)是一种重要的编程范式,它允许开发者创建复杂、可重用的代码结构。本指南将深入探讨JavaScript中的面向对象特性,包括类、对象、继承、封装和...
面向对象编程(Object-Oriented Programming,OOP)是JavaScript中的一个重要概念,它允许开发者以更加模块化、可复用的方式组织代码。下面将详细探讨JavaScript面向对象编程的基本原理、特性以及实际应用。 1. **...
面向对象编程(Object-Oriented Programming, OOP)是JavaScript中的核心概念,而设计模式则是解决常见编程问题的经验总结,对于提升代码质量和可维护性至关重要。这两本书——"JavaScript 面向对象编程.pdf"和...
首先,该文件提到的书籍是关于JavaScript面向对象编程的,面向对象编程(Object-Oriented Programming,简称OOP)是一种编程范式,它使用“对象”来设计软件。对象可以包含数据(以字段的形式)以及代码(以方法的...
### JavaScript学习深入—面向对象编程 #### 一、JavaScript中的类型概述 ...综上所述,JavaScript通过其灵活的类型系统和原型继承机制支持面向对象编程,这为开发者提供了强大的工具来构建复杂的应用程序。
面向对象编程应用 面向对象编程是一种编程范式,JavaScript作为一种基于对象的语言,广泛应用于Web开发中。面向对象编程的核心思想是将程序分解为对象和类,对象具有自己的属性和方法,而类则是对象的蓝图。下面是...
JavaScript面向对象编程是一种基于原型(Prototype)的编程范式,它是动态类型语言,允许开发者创建具有复杂特性的对象。在JavaScript中,面向对象主要通过构造函数、原型链和闭包来实现。以下是对这一主题的详细...
#### 二、JavaScript与面向对象编程 尽管JavaScript最初被设计为一种轻量级的脚本语言,并不是为了支持完整的面向对象编程而设计的,但它仍然可以通过原型链和类的方式实现面向对象编程。 ##### 1. 封装 封装是指...
面向对象编程(Object-Oriented Programming, OOP)是JavaScript的核心特性之一,它提供了多种模式来创建和操作对象。以下是对标题和描述中提到的几种JavaScript面向对象编程模式的详细解释: 1. **构造函数与字面...
在本文档中,我们将深入探讨设计模式及其在面向对象编程中的应用。设计模式是软件工程中的一套被广泛认可的最佳实践,它们是一些在特定上下文中反复出现的问题的解决方案。了解和应用设计模式可以帮助开发者写出更加...
总的来说,JavaScript中的面向对象编程与传统的基于类的OOP有所不同,它通过原型链和构造函数来实现对象的创建和继承。正确理解并运用这些概念,可以让开发者更有效地利用JavaScript进行面向对象的编程。
面向对象编程(Object-Oriented Programming,OOP)是一种强大的编程范式,它基于“对象”的概念,允许我们通过封装数据和方法来组织代码。在JavaScript中,面向对象编程并不是原生支持的,但它可以通过模拟类和对象...
JavaScript中实现面向对象编程的核心机制之一是构造函数和原型链。构造函数是一种特殊的函数,用于创建和初始化对象。例如: ```javascript function Person(name, email, website) { this.name = name; this....
面向对象编程(Object-Oriented Programming,简称 OOP)是一种编程范式,它将程序设计围绕“对象”进行组织。JavaScript 虽然是一种基于原型的语言,但同样支持面向对象编程,并且能够通过多种方式创建对象。 ####...