-
Notifications
You must be signed in to change notification settings - Fork 0
Description
类
在面向对象编程中, 类是一种面向对象计算机编程语言的构造,是创建对象的蓝图,描述了所创建的对象共同的属性和方法。 ——《维基百科》
简而言之,类是对象属性和方法的封装。
在传统面向对象语言中,以 Java 为例。Java 是一门传统的纯面向对象语言。
public class Person {
String name;
void showName() {
}
}原型
JavaScript 是一门弱面向对象多范式的动态类型语言。它没有提供传统面向对象语言中的类式继承,而是通过原型对象实现对象与对象之间的继承。
JavaScript 中的对象有一个特殊的 __proto__ 内置属性,其实就是对于其他对象的引用。
几乎所有的对象在创建时 __proto__ 属性都会被赋予一个非空的值。
在面向类的语言中,类可以被复制(或者说实例化)多次。但是在 JavaScript 中,并没有类似的复制机制,
不能创建一个类的多个实例,只能创建多个对象,它们的 __proto__ 关联的是同一个对象。
但是在默认情况下并不会进行复制,因此这些对象之间并不会完全失去联系,它们是相互关联的。
const Person = function(opt) {
this.name = opt.name;
this.age = opt.age;
};
Person.prototype = {
constructor: Person,
showName() {
return this.name;
}
};
const xiaoming = new Person({ name: "xiaoming", age: 18 });
const xiaohua = new Person({ name: "xiaohua", age: 18 });在 JavaScript 中, 我们并不会将一个对象('类')复制到另一个对象(实例),只是将它们关联起来。
继承
库中的使用
我们来看看类在 underscore.js 中的应用
// underscore.js v1.9.2
var _ = function(obj) {
/*
obj 为 new _() 的情况,直接返回该实例
*/
if (obj instanceof _) return obj;
/*
当开发者使用 _([]) 这样的模式,
*/
if (!(this instanceof _)) return new _(obj);
/*
其它情况下, 将 obj 参数赋值给 _wrapped 属性
*/
this._wrapped = obj;
};当我们以 _([1,2,3]) 方式使用 underscore.js 时,就把 _ 函数当做构造函数(即创建名为 _ 的"类"),
同时它的 __proto__ 指向它的原型对象 _.prototype。准确来讲,关联它原型对象上的属性和方法。
再看看 _.prototype 上定义的属性和方法。
// underscore.js v1.9.2
_.mixin = function(obj) {
_.each(_.functions(obj), function(name) {
var func = (_[name] = obj[name]);
_.prototype[name] = function() {
var args = [this._wrapped];
push.apply(args, arguments);
/*
最后都要返回 _ 实例,才能启用链式调用
this 指向 _.prototype
*/
return chainResult(this, func.apply(_, args));
};
});
/*
_ 是一个类
*/
return _;
};
_.mixin(_);在 _.mixin 函数的体内,通过 _.each 方法将 _ 函数(此时作对象使用)上的方法添加到 _.prototype 对象上,
由此,所有的 _ 实例均可以关联原型对象上的属性和方法。