Javascript高级程序设计第六七章
2015-07-30 21:28
573 查看
1.目前使用最广泛、认同度最高的一种创建自定义类型的方法
2.通过下面的函数可以确定属性存在与对象还是原型中
3.组合继承避免了原型链和借用构造函数的缺陷,融合了他们的优点,成为Javascript中最常用的继承模式。
原型链的缺点:
①原先的父类实例属性就顺利成章地变成了现在的原型属性,会被所有子类共享
②没有办法在不影响所有对象实例的情况下,给超类型的构造函数传递参数(原因是①)
但这些都被借用构造函数所解决
借用构造函数的缺点:方法都在构造函数中定义,因此函数复用无从谈起
原型链的注意点:
①给原型添加方法的代码一定要放在替换原型的语句之后
②不能通过对象字面量创建原型方法,等于改写原型了
4.闭包与变量
闭包:指的是有权访问另一个函数作用域中的变量的函数,常见方式,就是在一个函数内部创建另一个函数
作用域链中的这种配置机智引出了一个值得注意的副作用,即闭包只能取得包含函数中的任何变量的最后一个值。别忘了闭包所保存耳朵是整个变量对象,而不是某个特殊的变量
但是,我们可以通过创建另一个匿名哈数强制让闭包的行为符合预期
书上:由于函数传递是按值传递的,所以就会将变量i的当前值辅助给参数num,这样一来,result数组中的每个函数都有自己的num变量的一个副本
关于This对象
由于匿名函数的执行环境具有全局性,因此其this对象通常指向window
5.私有变量
严格来讲,Javascript没有私有成员的概念。但任何在函数中定义的变量,都可以认为是私有变量,因为不能在函数的外部访问到这些变量,私有变量包括函数的参数、局部变量和在函数内部定义的其他函数
特权方法:有权访问私有变量和私有函数的公有方法
第一种方法是在构造函数中定义特权方法
第二种方法是在私有作用域中定义私有变量和函数(生成静态私有变量,私有函数)
需要注意的是,这个模式在定义构造函数时没有使用函数声明,而是使用函数表达式,函数声明只能创建局部函数。出于同样的原因。我们在声明MyObject时也没使用var关键字,还有需要注意的是私有变量和私有函数是由实例共享的
6.模块模式
模块模式即为单例创建私有变量和特权方法
增强的模块模式
这种增强的模块模式适合那些单例必须是某种类型的实例,同时还必须添加某些属性和(或)方法对其加以增强的情况。
a8df
function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.friends = ["Shelby", "Court"]; } Person.prototype = { constructor: Person, sayName : function () { alert(this.name); } }; var person1 = new Person("Nicholas", 29, "Software Engineer"); var person2 = new Person("Greg", 27, "Doctor"); person1.friends.push("Van"); alert(person1.friends); //"Shelby,Court,Van" alert(person2.friends); //"Shelby,Court" alert(person1.friends === person2.friends); //false alert(person1.sayName === person2.sayName); //true
2.通过下面的函数可以确定属性存在与对象还是原型中
function hasPrototypeProperty(object, name){ return !object.hasOwnProperty(name) && (name in object)}
3.组合继承避免了原型链和借用构造函数的缺陷,融合了他们的优点,成为Javascript中最常用的继承模式。
function SuperType(name){ this.name = name; this.colors = ["red", "blue", "green"]; } SuperType.prototype.sayName = function(){ alert(this.name); }; function SubType(name, age){ SuperType.call(this, name); this.age = age; } SubType.prototype = new SuperType(); SubType.prototype.sayAge = function(){ alert(this.age); }; var instance1 = new SubType("Nicholas", 29); instance1.colors.push("black"); alert(instance1.colors); //"red,blue,green,black" instance1.sayName(); //"Nicholas"; instance1.sayAge(); //29 var instance2 = new SubType("Greg", 27); alert(instance2.colors); //"red,blue,green" instance2.sayName(); //"Greg"; instance2.sayAge(); //27
原型链的缺点:
①原先的父类实例属性就顺利成章地变成了现在的原型属性,会被所有子类共享
②没有办法在不影响所有对象实例的情况下,给超类型的构造函数传递参数(原因是①)
但这些都被借用构造函数所解决
借用构造函数的缺点:方法都在构造函数中定义,因此函数复用无从谈起
原型链的注意点:
①给原型添加方法的代码一定要放在替换原型的语句之后
②不能通过对象字面量创建原型方法,等于改写原型了
4.闭包与变量
闭包:指的是有权访问另一个函数作用域中的变量的函数,常见方式,就是在一个函数内部创建另一个函数
作用域链中的这种配置机智引出了一个值得注意的副作用,即闭包只能取得包含函数中的任何变量的最后一个值。别忘了闭包所保存耳朵是整个变量对象,而不是某个特殊的变量
function createFunctions(){ var result = new Array(); for (var i=0; i < 10; i++){ result[i] = function(){ return i; }; } return result; } var funcs = createFunctions(); //every function outputs 10 for (var i=0; i < funcs.length; i++){ document.write(funcs[i]() + "<br />"); }因为每个函数的作用域中都保存着createFunctions()函数的活动对象,所以它们引用的都是同一个变量i
但是,我们可以通过创建另一个匿名哈数强制让闭包的行为符合预期
function createFunctions(){ var result = new Array(); for (var i=0; i < 10; i++){ result[i] = function(num){ return function(){ return num; }; }(i); } return result; } var funcs = createFunctions(); //every function outputs 10 for (var i=0; i < funcs.length; i++){ document.write(funcs[i]() + "<br />"); }个人认为,因为传递给num的时候,其实就是一个值了,不是变量了
书上:由于函数传递是按值传递的,所以就会将变量i的当前值辅助给参数num,这样一来,result数组中的每个函数都有自己的num变量的一个副本
关于This对象
由于匿名函数的执行环境具有全局性,因此其this对象通常指向window
var name = "The Window"; var object = { name : "My Object", getNameFunc : function(){ //var that = this; return function(){ return that.name; }; } }; alert(object.getNameFunc()()); //"The Window"前面曾经提到,每个函数在被调用时都会自动取得两个特殊变量:this和arguments。内部函数在搜索这两个变量时,只会搜索其活动对象为止(getNameFuc),因此永远不可能直接访问到外部函数中的这两个变量。因此去掉上面的注释就可以了
5.私有变量
严格来讲,Javascript没有私有成员的概念。但任何在函数中定义的变量,都可以认为是私有变量,因为不能在函数的外部访问到这些变量,私有变量包括函数的参数、局部变量和在函数内部定义的其他函数
特权方法:有权访问私有变量和私有函数的公有方法
第一种方法是在构造函数中定义特权方法
function MyObject(){ //私有变量和私有函数 var privateVariable = 10; function privateFunction() { return false; } //特权方法 this.publicMethod = function(){ privateVariable++; return privateFunction(); };}利用的也是闭包的原理
第二种方法是在私有作用域中定义私有变量和函数(生成静态私有变量,私有函数)
(function(){ var name = ""; Person = function(value){ name = value; }; Person.prototype.getName = function(){ return name; }; Person.prototype.setName = function (value){ name = value; }; })(); var person1 = new Person("Nicholas"); alert(person1.getName()); //"Nicholas" person1.setName("Greg"); alert(person1.getName()); //"Greg" var person2 = new Person("Michael"); alert(person1.getName()); //"Michael" alert(person2.getName()); //"Michael"
需要注意的是,这个模式在定义构造函数时没有使用函数声明,而是使用函数表达式,函数声明只能创建局部函数。出于同样的原因。我们在声明MyObject时也没使用var关键字,还有需要注意的是私有变量和私有函数是由实例共享的
6.模块模式
模块模式即为单例创建私有变量和特权方法
function BaseComponent(){ } function OtherComponent(){ } var application = function(){ //private variables and functions var components = new Array(); //initialization components.push(new BaseComponent()); //public interface return { getComponentCount : function(){ return components.length; }, registerComponent : function(component){ if (typeof component == "object"){ components.push(component); } } }; }(); application.registerComponent(new OtherComponent()); alert(application.getComponentCount()); //2简言之,如果必须创建一个对象并以某些数据对其进行初始化,同时还要公开一些能够访问这些私有数据的方法,那么久可以使用模块模式。
增强的模块模式
这种增强的模块模式适合那些单例必须是某种类型的实例,同时还必须添加某些属性和(或)方法对其加以增强的情况。
function BaseComponent(){ } function OtherComponent(){ } var application = function(){ //private variables and functions var components = new Array(); //initialization components.push(new BaseComponent()); //create a local copy of application var app = new BaseComponent(); //public interface app.getComponentCount = function(){ return components.length; }; app.registerComponent = function(component){ if (typeof component == "object"){ components.push(component); } }; //return it return app; }(); alert(application instanceof BaseComponent); application.registerComponent(new OtherComponent()); alert(application.getComponentCount()); //2
a8df
相关文章推荐
- pjsip在vs2013中编译和使用
- Html JS实现表单验证
- WCF Ajax Json的应用
- WCF Ajax Json的应用
- JS图片自动和可控的轮播切换特效
- 01_js中常用的设计模式
- ASP.NET MV 4000 C - html.beginForm在javascript中获取form信息
- JavaScript跨域总结与解决办法
- [BZOJ1015][JSOI2008]星球大战starwar
- Jsp的基本原理
- json实现部门二级联动
- 利用json从后端取数据
- JavaScript 的同源策略
- JavaScript的类型转换(字符转数字,数字转字符)
- 使用Jsoup库解析HTML、XML或URL链接中的DOM节点
- JSTL中<fmt:bundle >找不到properties文件的原因
- BZOJ 2208 [Jsoi2010]连通数 tarjan缩点+bitset优化DP
- JSON详解
- ajax请求跨域问题-通过jsonp方式解决
- js 弹出alert框