编程语言按照数据类型大体分为: 静态类型语言 和 动态类型语言 。
静态类型语言在编译时便已确定变量的类型,而动态类型语言的变量类型要到程序运行时,待变量被赋予某个值之后,才会具有某种类型。
在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