Javascript设计模式学习一
学习Javascript设计模式之前,需要先了解一些相关知识,面向对象的基础知识、this等重要概念,以及掌握一些函数式编程的技巧。
Js多态
多态的思想:实际上是把“做什么”和“谁去做”分离开来。
例:
var makeSound = function(animal){ if(animal.show instanceof Function){ animal.show(); } } var dog = { show: function(){ console.log('汪汪'); } } var cat = { show: function(){ console.log('喵喵'); } } makeSound(dog); //输出:汪汪 makeSound(cat); //输出:喵喵
Js封装
例:
var myObject = (function(){ var name = 'hello'; return { getName: function(){ return name; } } })(); console.log(myObject.getName()); //hello console.log(myObject.name); //undefined
this的指向:
1.当函数作为对象的方法调用时,this指向该对象
var obj = { name: 'hello', getName: function(){ console.log(this===obj); //true console.log(this.name); //hello } } obj.getName();
2.当函数作为普通函数调用时,this指向全局对象即window对象
window.name = 'globalName'; var getName = function(){ return this.name; }; console.log(getName()); //globalName //或者 window.name = 'globalName'; var myObject = { name: 'hello', getName: function(){ return this.name; } }; var getName = myObject.getName; console.log(getName()); //globalName
3.构造器调用,构造器里的this指向返回的这个对象
var myClass = function(){ this.name = 'Class'; } var obj = new myClass(); console.log(obj.name); //Class
4.Function.prototype.call或Function.prototype.apply调用,可以动态地改变传入函数的this
var obj1 = { name: 'hello', getName: function(){ return this.name; } }; var obj2 = { name: 'hi' }; console.log(obj1.getName()); //hello console.log(obj1.getName.call(obj2)); //hi
call 和 apply
作用是一模一样的,区别仅在于传入参数形式不同。
apply接受两个参数,第一个参数指定了函数体内this对象的指向,第二个参数是一个带下标的集合,这个集合可以数组,也可以是类数组。
var func = function(a,b,c){ console.log([a,b,c]); //[1,2,3] } func.apply(null,[1,2,3]);
这段代码中,参数1、2、3放在数组中一起传入func函数,分别对应a、b、c,第一参数为null,函数体this指向默认宿主对象,浏览器中则是window。
call传入的参数数量不固定,第一个参数也是代表函数体内的this指向,从第二个参数起往后,每个参数依次传入函数。
call 和 apply 的用途
1.改变this指向
var obj1 = { name: 'objName' }; window.name = 'window'; var getName = function(){ console.log(this.name); }; getName(); //window getName.call(obj1); //objName
2.借用其他对象的方法
var A = function(name){ this.name = name; }; var B = function(){ console.log(arguments); A.apply(this,arguments); }; B.prototype.getName = function(){ return this.name; }; var b = new B('hello'); console.log(b.getName()); //hello