javascript-代码复用模式
2014-12-20 15:07
507 查看
代码复用模式
1)使用原型继承
函数对象中自身声明的方法和属性与prototype声名的对象有什么不同:
自身声明的方法和属性是静态的, 也就是说你在声明后,试图再去增加新的方法或者修改已有的方法,
并不会由其创建的对象产生影响,也即继承失败。
而prototype可以动态地增加新的方法或者修改已有的方法, 从而是动态的,一旦父函数对象声明了相关的prototype属性,由其创建的对象会自动继承这些prototype的属性。
既然有函数对象本身的属性, 也有prototype的属性, 那么是由其创建的对象是如何搜索相应的属性的呢?
基本是按照下面的流程和顺序来进行:
1 先去搜索函数对象本身的属性,如果找到立即执行
2 如果1没有找到,则会去搜索prototype属性,有2种结果,找到则直接执行,否则继续搜索父对象的父对象的prototype,
直至找到,或者到达prototype chain 的结尾(结尾会是Object对象)
上面也回答如果函数对象本身的属性与prototype属性相同(重名)时的解决方式, 函数本身的对象优先。
实例:
Js代码
function Employee(name)
{
this.name = "";
this.dept = "general";
this.gender = "unknown";
}
function WorkerBee()
{
this.projects = [];
this.hasCar = false;
}
WorkerBee.prototype = new Employee; // 第一层prototype链
function Engineer()
{
this.dept = "engineer"; //覆盖了 "父对象"
this.language = "javascript";
}
Engineer.prototype = new WorkerBee; // 第二层prototype链
var jay = new Engineer("Jay");
if (flag)
{
alert(jay.dept); //engineer, 找到的是自己的属性
alert(jay.hasCar); // false, 搜索到的是自己上一层的属性
alert(jay.gender); // unknown, 搜索到的是自己上二层的属性
}
2)使用Object.create继承对象
ECMAScript5也提供了类似的一个方法叫做Object.create用于继承对象。
实例:
Js代码
var parent = {
name : "张三"
};
/* 使用新版的ECMAScript 5提供的功能 */
var child = Object.create(parent, {
age : {
value : 2
},
sex : {
value : '男'
}
});
console.log("child.age.value: " + child.age + "-----sex: " + child.sex);
//child.age.value: 2-----sex: 男
3)使用Object.defineProperty(可以更细粒度的对新增的属性进行配置设置)
语法:
Object.defineProperty(obj, prop, descriptor)
参数:
obj:目标对象
prop:需要定义的属性或方法的名字。
descriptor:目标属性所拥有的特性。
可供定义的特性列表:
value:属性的值
writable:如果为false,属性的值就不能被重写。
get: 一旦目标属性被访问就会调回此方法,并将此方法的运算结果返回用户。
set:一旦目标属性被赋值,就会调回此方法。
configurable:如果为false,则任何尝试删除目标属性或修改属性以下特性(writable, configurable, enumerable)的行为将被无效化。
enumerable:是否能在for...in循环中遍历出来或在Object.keys中列举出来。
实例:
Js代码
var foo = {x:10};
Object.defineProperty(foo, "y", {
value:20,
writable: false,//只读
configurable: false, //不可配置
enumerable: true
});
console.log(foo.y); //20
4)通过call或apply方法
方法定义
call方法:
语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]])
定义:调用一个对象的一个方法,以另一个对象替换当前对象。
说明:
call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。
如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。
apply方法:
语法:apply([thisObj[,argArray]])
定义:应用某一对象的一个方法,用另一个对象替换当前对象。
说明:
如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。
如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj, 并且无法被传递任何参数。
说明:call, apply,这两个方法基本上是一个意思,区别在于 call 的第二个参数可以是任意类型,而apply的第二个参数必须是数组,也可以是arguments
实例:
Js代码
function Animal(name){
this.name = name;
this.showName = function(){
alert(this.name);
}
}
function Cat(name){
Animal.call(this, name);
}
var cat = new Cat("Black Cat");
cat.showName(); //Black Cat
//Animal.call(this) 的意思就是使用 Animal对象代替this对象,那么 Cat中不就有Animal的所有属性和方法了
//此时Cat对象就能够直接调用Animal的方法以及属性了.
1)使用原型继承
函数对象中自身声明的方法和属性与prototype声名的对象有什么不同:
自身声明的方法和属性是静态的, 也就是说你在声明后,试图再去增加新的方法或者修改已有的方法,
并不会由其创建的对象产生影响,也即继承失败。
而prototype可以动态地增加新的方法或者修改已有的方法, 从而是动态的,一旦父函数对象声明了相关的prototype属性,由其创建的对象会自动继承这些prototype的属性。
既然有函数对象本身的属性, 也有prototype的属性, 那么是由其创建的对象是如何搜索相应的属性的呢?
基本是按照下面的流程和顺序来进行:
1 先去搜索函数对象本身的属性,如果找到立即执行
2 如果1没有找到,则会去搜索prototype属性,有2种结果,找到则直接执行,否则继续搜索父对象的父对象的prototype,
直至找到,或者到达prototype chain 的结尾(结尾会是Object对象)
上面也回答如果函数对象本身的属性与prototype属性相同(重名)时的解决方式, 函数本身的对象优先。
实例:
Js代码
function Employee(name)
{
this.name = "";
this.dept = "general";
this.gender = "unknown";
}
function WorkerBee()
{
this.projects = [];
this.hasCar = false;
}
WorkerBee.prototype = new Employee; // 第一层prototype链
function Engineer()
{
this.dept = "engineer"; //覆盖了 "父对象"
this.language = "javascript";
}
Engineer.prototype = new WorkerBee; // 第二层prototype链
var jay = new Engineer("Jay");
if (flag)
{
alert(jay.dept); //engineer, 找到的是自己的属性
alert(jay.hasCar); // false, 搜索到的是自己上一层的属性
alert(jay.gender); // unknown, 搜索到的是自己上二层的属性
}
2)使用Object.create继承对象
ECMAScript5也提供了类似的一个方法叫做Object.create用于继承对象。
实例:
Js代码
var parent = {
name : "张三"
};
/* 使用新版的ECMAScript 5提供的功能 */
var child = Object.create(parent, {
age : {
value : 2
},
sex : {
value : '男'
}
});
console.log("child.age.value: " + child.age + "-----sex: " + child.sex);
//child.age.value: 2-----sex: 男
3)使用Object.defineProperty(可以更细粒度的对新增的属性进行配置设置)
语法:
Object.defineProperty(obj, prop, descriptor)
参数:
obj:目标对象
prop:需要定义的属性或方法的名字。
descriptor:目标属性所拥有的特性。
可供定义的特性列表:
value:属性的值
writable:如果为false,属性的值就不能被重写。
get: 一旦目标属性被访问就会调回此方法,并将此方法的运算结果返回用户。
set:一旦目标属性被赋值,就会调回此方法。
configurable:如果为false,则任何尝试删除目标属性或修改属性以下特性(writable, configurable, enumerable)的行为将被无效化。
enumerable:是否能在for...in循环中遍历出来或在Object.keys中列举出来。
实例:
Js代码
var foo = {x:10};
Object.defineProperty(foo, "y", {
value:20,
writable: false,//只读
configurable: false, //不可配置
enumerable: true
});
console.log(foo.y); //20
4)通过call或apply方法
方法定义
call方法:
语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]])
定义:调用一个对象的一个方法,以另一个对象替换当前对象。
说明:
call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。
如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。
apply方法:
语法:apply([thisObj[,argArray]])
定义:应用某一对象的一个方法,用另一个对象替换当前对象。
说明:
如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。
如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj, 并且无法被传递任何参数。
说明:call, apply,这两个方法基本上是一个意思,区别在于 call 的第二个参数可以是任意类型,而apply的第二个参数必须是数组,也可以是arguments
实例:
Js代码
function Animal(name){
this.name = name;
this.showName = function(){
alert(this.name);
}
}
function Cat(name){
Animal.call(this, name);
}
var cat = new Cat("Black Cat");
cat.showName(); //Black Cat
//Animal.call(this) 的意思就是使用 Animal对象代替this对象,那么 Cat中不就有Animal的所有属性和方法了
//此时Cat对象就能够直接调用Animal的方法以及属性了.
相关文章推荐
- JavaScript代码复用模式详解
- 简单谈谈javascript代码复用模式
- 初涉JavaScript模式 (13) : 代码复用 【上】
- 深入理解JavaScript系列(46):代码复用模式(推荐篇)
- javascript优化--08模式(代码复用)01
- javascript代码复用模式(二)
- 复制所有属性进行继承 转自 博客园 汤姆大叔 深入理解JavaScript系列(46):代码复用模式(推荐篇)
- 简单谈谈javascript代码复用模式
- javascript代码复用模式-----现代继承
- JavaScript代码复用模式
- JavaScript代码复用模式实例分析
- 深入理解JavaScript系列(46):代码复用模式(推荐篇)
- 自我学习——javascript——代码复用常见模式
- 深入理解JavaScript系列(46):代码复用模式(推荐篇)
- javascript代码复用模式
- 深入理解JavaScript系列(45):代码复用模式(避免篇)
- JavaScript代码复用模式实例分析
- 深入理解JavaScript系列(46):代码复用模式(推荐篇)
- 简单谈谈javascript代码复用模式
- javascript代码复用模式