《JavaScript设计模式与开发实践》-面向对象的JavaScript

动态类型语言

编程语言按照数据类型大体分为:静态类型语言动态类型语言

静态类型语言在编译时便已确定变量的类型,而动态类型语言的变量类型要到程序运行时,待变量被赋予某个值之后,才会具有某种类型。

在JavaScript中,当我们对一个变量赋值时,显然不需要考虑它的类型,因此JavaScript是一门典型的动态类型语言

动态类型语言对变量类型的宽容给实际编码带来了很大的灵活性,由于无需进行类型检测,我们可以尝试调用任何对象的任意方法,而无需去考虑它原本是否被设计为拥有该方法。

这一切都建立在鸭子类型的概念上,即如果它走起来像鸭子,叫起来也是鸭子,那么它就是鸭子

var duck = {
   duckSinging: function() {
     printf('gagaga');
   }
 };
 var chicken = {
   duckSinging: function() {
     printf('gagaga');
   }
 };
 var choir = [];

 var joinChoir = function(animal) {
   if (animal && typeof animal.duckSinging === "function") {
     choir.push(animal);
     printf("恭喜加入合唱团");
     printf("合唱团已有人数" + choir.length);
   }
 }

 joinChoir(duck);
 joinChoir(chicken);

由此,实现了动态类型语言中的一个重要原则:面向接口编程,而不是面向实现编程

多态

多态的实际含义是:同一操作作用域不同的对象上面,可以产生不同的解释和不同的执行结果。

 var makeSound = function(animal) {
   if (animal instanceof Duck) {
     printf('ggaga');
   } else if (animal instanceof chicken) {
     printf('gegege');
   }
 }

 var Duck = function() {};
 var chicken = function() {};

 makeSound(new Duck());
 makeSound(new chicken());

这段代码确实实现了多态性,但是如何增加一只动物,那么makeSound函数也需要去改动,这显然并不让人满意。

多态背后的思想是将“做什么”和“谁去做及怎样做”分离开来,也就是将“不变的事物”与“可能改变的事物”分离开来

原型编程范型的一些规则

  • 所有的数据都是对象

  • 要得到一个对象,不是通过实例化类,而是找到一个对象作为原型并克隆它

  • 对象会记住它的原型

  • 如果对象无法响应某个请求,它会把这个请求委托给它自己的原型

事实上,JavaScript中的根对象是Object.prototype,它是一个空对象,我们在JavaScript中遇到的每个对象,实际上都是从它克隆而来的。Object.prototype就是它们的原型。

虽然我们经常用new去实例化一个函数,但是在JavaScript中,当使用new运算符来调用函数时,实际上也是先克隆Object.prototype对象,再进行一些其他额外的过程。

我们一直在讨论对象的原型,就JavaScript的真正实现来说,并不能说对象有原型,而应该说对象的构造器有原型。

实际上,虽然JavaScript的对象最初都是又Object.prototype对象克隆而来,但对象构造器的原型并不限于Object.prototype上,而是可以动态指向其他对象。这样一来,当对象a需要借用对象b的能力时,可以有选择性地把对象a的构造器的原型指向对象b,从而达到继承的效果。

var A=function(){};
A.prototype={name:'sven'};

var B=function(){};
B.prototype.new A();

var b=new B();
console.log(b.name);//输出:sven
posted @ 2015-12-26 00:50  司想君  阅读(684)  评论(2编辑  收藏  举报