JavaScript OOP
tudent.prototype=Object.create(Person.prototype);
Student.prototype.constructor=Student;
Object.create()创建一个空对象指向它的原型Object.create()创建一个新的空对象,
让Student.prototype指向于它,从而避免了与Person.prototype指向同一对象。
进而可以让Student单独创建属于自己的函数,而不影响到Person,
这样做了之后Student.prototype.constructor会指向Person,因此为了避免混乱,
需要用Student.prototype.constructor = Student 把它修改为指向Student
一般对象的原型都会指向 Object.prototype。
特例: 并不是所有对象的原型链上都会有 Object.prototype,
比如var obj=Object.create(null); 并不是所有函数对象都会有prototype属性,bind 函数(用来给函数绑定this)
获取原型的方式(chrome浏览器):
fun.prototype.__proto__;
fun.prototype.__proto__=== Object.prototype返回true/false来判断
Object.getPrototypeOf(obj)===Object.prototype
prototype的修改
动态修改prototype的属性时,是会影响所有已创建或者新创建的实例的,
但是如果修改整个prototype赋值为新的对象的话,对已经创建的实例是不会修改的,但是会影响后续创建的实例
instanceof
1.instanceof左边一般是对象,右边是一个函数(构造器)。假如右边不是函数对象,会报错;假如左边不是对象,会直接返回false;
2.instanceof用来判断右边构造器的prototype属性是否出现在左边对象的原型链上;
3.从js的解释器层面来讲,instanceof是比对对象的,执行环境不同,构造器不同,instanceof方法失效(不同window和iframe之间的对象类型检测不能使用instanceof)
实现继承的方法:
1. Student.prototype = Person.prototype;( 不推荐 )
2. Student.prototype = new Person(); 这种方式如果构造器有参数就不好传参数;
3. Student.prototype = Object.create(Person.prototype);
模拟重载:
通过判断实际传入的参数的个数实现模拟的重载。
Object.seal(x.prototype),初始化之后不可以扩展或配置了;
链式调用:
function ClassManager(){
ClassManager.prototype.addClass=function(str){
console.log('Class'+str+'added');
return this;
}
}
var manager=new ClassManager();
manager.addClass('ClassA').addClass('ClassB').addClass('ClassC');
//Class:ClassA added
//Class:ClassB added
//Class:ClassC added
js的链式调用实现的核心技术是返回一个对象,这个对象保存了前一个对象的成员变量,
成员函数有两个作用 一个是设置或改变成员变量,一个作用是获取成员变量,所以在设置的函数中,
需要return this,this指向的 是当前这个对象,获取型的函数不需要返回this!
简单的链式调用:
function A(){}
A.prototype.add = function(s){
console.log(s);
return this; // 返回A的实例,实现链式调用
}
调用基类方法:
function A(name) { this.name = name; }
A.prototype.mm = function(){};
function B(age) {
this.age = age;
A.call(this, name); // 调用基类的方法或属性
}
B.prototype.mm = function(){
A.prototype.mm.apply(this, arguments); // 调用基类的原型方法或属性 ……
}
模块化方案: 1、对象(暴露所有模块成员)
var mod = {
n: 0,
f: function(){...}
};
2、立即执行函数(无法访问未return的私有变量)
var mod = (function(){
var _n = 0;
var f = function(){...};
return {n:_n, f:f};
})();
3、函数实例(同上)
var mod = new function(){
var _n = 0;
var f = function(){...};
this.n = _n;
this.f = f;
};
实例——探测器: !function(global){ // 基类 function Base(configs){ if(!(this instanceof Base)) throw new Error("需要用new调用"); this.configs = configs; this.analyze(); } Base.prototype.detect = function(){throw new Error("抽象方法");}; Base.prototype.analyze = function(){...}; // 具体类 function Link(links){ if(!(this instanceof Link)) throw new Error("..."); this.links = links; Base.apply(this, arguments); } // 先继承,再拓展,防覆盖 Link.prototype = Object.create(Base.prototype); Link.prototype.contructor = Link; Link.prototype.detect = function(){...}; //冻结方法,防止被改变,ES5 Object.freeze(Base); Object.freeze(Base.prototype); Object.freeze(Link); Object.freeze(Link.prototype); // 暴露到外层global Object.defineProperties(global,{ Link: {value: Link}, Base: {value: Base} }); }(this)