#1默认原型继承
function inherint(C,P){
C.prototype = new P();
}
function Parent(name){
this.name =name||"Adam";
}
Parent.prototype.say = function(){
return this.name;
}
function Child(name){
// this.name = name;
}
inherint(Child,Parent);
var kid = new Child("lishuang");
kid.say();//"Adam"
this---
Child {name: "Adam", say: function}
缺点:
1继承了两个对象上的属性即添加到this上的和添加到原型上的,多数时不许这些自身属性
2每次需要一个子类都要调用继承函数
3原型上的引用属性会共享
#2借用构造函数
// 借用构造函数
function Article(){
this.tags =['js','css'];
}
var article = new Article();
function BlogPost(){}
BlogPost.prototype = article;
var blog = new BlogPost();
// 注意以上不在需要new Article() 因为已经有了可用实例
function StaticPage(){
Article.call(this);
}
var page = new StaticPage();
console.log(article.hasOwnProperty('tags'));
console.log(blog.hasOwnProperty('tags')); // 获取的是原型上引用
console.log(page.hasOwnProperty('tags')); //会创建一个副本而不是引用
true
false
true
//缺点:
无法从原型中继承任何东西,且原型也仅是添加可重用方法以及属性的位置不会为每个实力重新创建原型
、、优点
可以获得父对象自身成员的真实副本不存在子对象意外覆盖父对象属性的风险
#3 借用和设置原型
function Parent(name){
this.name =name||"Adam";
}
Parent.prototype.say = function(){
return this.name;
}
function Child(name){
Parent.apply(this,arguments);
}
Child.prototype = new Parent();
var kid = new Child("lishuang");
kid.name;
"lishuang"
kid.say()
"lishuang"
delete kid.name
true
kid.say()
"Adam"
#4 共享原型链------子孙对象修改原型会改变父对象的原型
function inherint(C,P){
C.prototype=P.prototype;
}
#5临时构造函数
function inherit(C,P){
var F = function(){};
F.prototype = P.prototype;
C.prototype = new F();
}
存储超类
function inherit(C,P){
var F = function(){};
F.prototype = P.prototype;
C.prototype = new F();
C.uber = P.prototype;
}
重置构造函数
var inherit = (function(){
var F = function(){};
return function(C,P){
F.prototype = P.prototype;
C.prototype = new F();
C.uber = P.prototype;
C.prototype.constructor = C;
}
}())
5原型继承
function object(o){
function F(){};
F.prototype = o;
return new F();
}
function Person(){
this.name = "Adam";
}
Person.prototype.getName =function(){
return this.name;
}
var para = new Person();
var kid = object(para);//改进var kid = object(Person.prototype);
kid.getName();
ECMAscript5 里用Object.create()实现
Object(parent,{})第二个参数可选
YUI3 Y.Object()方法
YUI().use('*',function(Y){
var child = Y.Object(parent);
})
6// 通过复制来实现继承
// 浅复制当属性是对象数组时会通过饮用传递存在修改父元素的风险
function extend(parent,child){
var i;
child = child ||{};
for(i in parent){
child[i] = parent[i];
}
return child;
}
// 深赋值
function extendDeep(parent,child){
var i,
tostr=Object.prototype.toString,
astr = "[object Array]";
child=child||{};
for(i in parent){
if(parent.hasOwnProperty(i)){
if(typeof parent[i] ==="object"){
child[i] = (tostr.call(parent[i]))===astr?[]:{};
extendDeep(parent[i],child[i]);
}else{
child[i] = parent[i];
}
}
}
return child;
}
函数绑定解决、回调函数与函数表达式的this指向全局对象问题
var one = {
name :"obj",
say:function(greet){return greet+", " + this.name;}
}
one.say('hi');
//"hi, obj"
var say = one.say; say('hi');
//"hi, "
function bind(o,m){
return function(){
return m.apply(o,[].slice.call(arguments));//闭包是的函数返回后仍可访问o/m
};
}
ES5 中Function.prototype.bind的实现
if(typeof Function.prototype.bind==="undefined"){
Function.prototype.bind = function(thisArg){
var fn = this,
slice = Array.prototype.slice,
arg= slice.call(arguments,1);
return function(){
return fn.apply(thisArg,arg.concat(slice.call(arguments)));
}
}
}