javascript: 基于原型的面向对象编程
2016-04-30 00:11
651 查看
Douglas Crockford指出javascript是世界上最被误解的编程语言。由于javascript缺少常见的面向对象概念,许多程序猿认为javascript不是一个合适的语言。我在做第一个javascript项目时候也发现不能将代码放在一个类中。其实大部分程序猿不知道javascript可以面向对象。
浏览器大战时代,Netscape的执行官招来了一个叫Brendan Eich的聪明人,发明了livescript(就是现在的javascript)语言,用来运行在浏览器端。它不像c++和java一样基于类,而是基于原型继承模型设计的。 OOP非常适合livescript这种动态语言。
由于当时市场影响,这种新的语言需要看起来像java。java在当时非常耀眼流行,Netscape的执行官希望新语言是”java的小兄弟“。这就是为啥新语言叫javascript。
genericAnimal就是一个对象,可以这样使用:
我们可以使用genericAnimal作为原型,创建其他对象,就像拷贝对象(cloning the object):
我们创建了cat对象,cat对象是genericAnimal的clone版。将cat对象作为原型,创建其他对象:
puff对象可以使用“父对象”继承来的属性和方法:
实现继承有点复杂, Ninja对象继承Person对象:
使用genericAnimal作为原型创建一个新的空对象:
capybara对象虽然没有size属性,但是它可以在原型链上查找size属性:当调用
浏览器大战时代,Netscape的执行官招来了一个叫Brendan Eich的聪明人,发明了livescript(就是现在的javascript)语言,用来运行在浏览器端。它不像c++和java一样基于类,而是基于原型继承模型设计的。 OOP非常适合livescript这种动态语言。
由于当时市场影响,这种新的语言需要看起来像java。java在当时非常耀眼流行,Netscape的执行官希望新语言是”java的小兄弟“。这就是为啥新语言叫javascript。
JavaScript and prototype-based OOP
下面是javascript的oop例子,先来搞出一个animal的对象:var genericAnimal = Object.create(null);
Object.create(null)创建空对象。下面往这个新对象上添加新属性和方法:
genericAnimal.name = 'Animal'; genericAnimal.gender = 'femal'; genericAnmal.description = function () { return 'Gender: ' + this.gender + '; Name: ' + this.name; };
genericAnimal就是一个对象,可以这样使用:
console.log(genericAnimal.description());
我们可以使用genericAnimal作为原型,创建其他对象,就像拷贝对象(cloning the object):
var cat = Object.create(genericAnimal);
我们创建了cat对象,cat对象是genericAnimal的clone版。将cat对象作为原型,创建其他对象:
var colonel = Object.create(cat); colonel.name = 'Colonel Meow'; var puff = Object.create(cat); puff.name = 'Puffy';
puff对象可以使用“父对象”继承来的属性和方法:
console.log(puff.description()); //Gender: female; Name: Puffy
The new keyword and the constructor function
javascript有new关键字和构造函数的感念。function Person(name) { this.name = name; this.sayName = function() { return "Hi, I'm " + this.name; }; } var adam = new Person('Adam');
实现继承有点复杂, Ninja对象继承Person对象:
function Ninja(name, weapon) { Person.call(this, name); this.weapon = weapon; } Ninja.prototype = Object.create(Person.prototype); Ninja.prototype.constructor = Ninja;
Understanding delegation and the implementation of prototypes
使用Object.create创建新对象时候,传入的对象成了新对象的原型。每个对象都有默认的
__proto__属性来记录原型。举例说明:
var genericAnimal = Object.create(null); // genericAnimal.__proto__ points to null
使用genericAnimal作为原型创建一个新的空对象:
var rodent = Object.create(genericAnimal); rodent.size = 'S'; var capybara = Object.create(rodent); //capybara.__proto__ points to rodent //capybara.__proto__.__proto__ points to genericAnimal //capybara.__proto__.__proto__.__proto__ is null
capybara对象虽然没有size属性,但是它可以在原型链上查找size属性:当调用
capybara.size时,首先在capybara对象的本身属性上查找,如果没有找到,则会去
capybara.__proto__所指向的原型上去查找。如果在
capybara.__proto__也没有找到,则继续在
capybara.__proto__.__proto__上查找。
Creating Object.create
如果有些浏览器不支持Object.create,那么需要自己实现了:
if (typeof Object.create !== 'function') { Object.create = function (o) { function F() {} F.prototype = o; return new F(); }; }
相关文章推荐
- JQuery1——基础($对象,选择器,对象转换)
- Android学习笔记(二九):嵌入浏览器
- Android java 与 javascript互访(相互调用)的方法例子
- JavaScript演示排序算法
- javascript实现10进制转为N进制数
- 最后一次说说闭包
- Ajax
- 2019年开发人员应该学习的8个JavaScript框架
- HTML中的script标签研究
- 对一个分号引发的错误研究
- 异步流程控制:7 行代码学会 co 模块
- ES6 走马观花(ECMAScript2015 新特性)
- JavaScript拆分字符串时产生空字符的原因
- Canvas 在高清屏下绘制图片变模糊的解决方法
- Redux系列02:一个炒鸡简单的react+redux例子
- JavaScript 各种遍历方式详解
- call/apply/bind 的理解与实例分享