阴影中的曙光

[旧]JavaScript与OOP

2018.03.31 / JavaScript / 点击 296 / 回复 0 / 旧站搬运, JavaScript

随便记点笔记,因为也是刚开始系统学习JavaScript,所以难免有理解错的地方,且看且过吧Orz

关于arguments

函数中arguments.callee();用于代替自身函数名,可以用再递归函数防止函数名耦合.
arguments.callee.caller;为调用次函数的函数

function show(){
    console.log(arguments.callee);
    console.log(arguments.callee.caller);
}
function call(){
    show();
}
call();

/***输出结果***/
[Function: show]
[Function: call]

关于call

call可以替换上下文关系


function cat() {}
cat.prototype = {
    food: "fish",
    say: function() {
        console.log("I love " + this.food);
    }
}
var Cat = new cat;
Cat.say();

Dog = { food: "bone" }
Cat.say.call(Dog); //say视为Dog调用.
/*****输出结果*****/
I love fish
I love bone

主流类实现方法

采用构造函数跟原型结合的方式创建,构造函数定义私有属性及方法,原型创建公共属性方法.通过cat类实例了两个对象(tom&jay),他们有公共的属性(like:fish)和方法(sleep),并且有自己私有的名字颜色和自我介绍

function cat(color, name) {
    this.color = color;
    this.name = name;
    this.say = function() {
        console.log("I am " + name + ". I am " + color + "cat");
    }
}
cat.prototype = {
    leg: "four",
    like: "fish",
    sleep: function() {
        console.log("I,sleep");
    }
}
var tom = new cat("black", "tom");
var jay = new cat("yellow", "joy");
tom.say();
tom.sleep();
console.log("tom like" + tom.like);
jay.say();
jay.sleep();
console.log("tom like" + jay.like);
/*****输出结果*****/
[Running] node "/Users/dawn/Desktop/Untitled-2.js"
I am tom. I am blackcat
I,sleep
tom likefish
I am joy. I am yellowcat
I,sleep
tom likefish

继承

function cat (){
   this.lag=4;
  //父级 ,创建函数以构造函数的方式
}
cat.prototype.showlag = function(){
    return this.lag;
    //父级方法
}
function blackcat(){
//子级
    this.color="black";
}
blackcat.prototype = new cat();
//继承
blackcat.prototype.showcolor=function(){
    return this.color;
    //子级方法
}
var tom=new blackcat();
console.log(tom.showcolor());
console.log(tom.showlag());
/*******输出******/
black
4

原型链式的继承无法满足父级类的数据独立,一个继承的子对象修改了父类中数据会反应在其他子对象实例中,解决方案如下

function cat() {
    this.like = ['fish', 'bird'];
}

function blackcat() {
    cat.call(this);
}

function withecat() {
    cat.call(this);
}
var tom = new blackcat();
tom.like.push("jay");

var tom3 = new blackcat();
tom3.like.push("jay3");
var tom2 = new withecat();
tom2.like.push("joy2");

console.log(tom.like);
console.log(tom2.like);
console.log(tom3.like);
/********实现方式如下*********/
[ 'fish', 'bird', 'jay' ]
[ 'fish', 'bird', 'joy2' ]
[ 'fish', 'bird', 'jay3' ]



升级版组合继承,通过构造函数实现继承父类并且可以传参数.



function cat(name, age) {
    this.name=name;
    this.age=age;
    this.like = ['fish', 'bird'];

}
cat.prototype.say = function() {
    console.log("i,am " + this.name + " i "+this.age+" years" );
}

function blackcat(name, color,age) {
    this.color = color;
    cat.call(this, name , age);
}
blackcat.prototype = new cat();
blackcat.prototype.constructor = cat();
blackcat.prototype.saycolor = function() {
    console.log(this.color);
}
var tom = new blackcat("tom", "black",2);
tom.like.push("jay");
console.log(tom.like);
tom.saycolor();
tom.say();
   /**********输出结果************/  
[ 'fish', 'bird', 'jay' ]
black
i,am tom i 2 years

### 原型式继承

      function zpy(o) {
        function F() {};
        F.prototype = o;
        return new F();
    }

var cat = {
    color: "white",
    like: ["fish", "bird"]
};
var tom = zpy(cat);
tom.color = "black";
tom.like.push("jay");
var tom2 = zpy(cat);

//tom2.like.push("tom");
console.log(tom.like + " " + tom.color);
console.log(tom2.like + " " + tom2.color);
/**********结果***********/
fish,bird,jay black
fish,bird,jay white

本质上只是父级元素浅复制出一些子对象,每个子对象都贡献父元素中数据,除了重写的属性独立外其他都共享.简化版:


var cat = {
    color: "white",
    like: ["fish", "bird"]
};
var tom = Object.create(cat);
tom.color = "black";
tom.like.push("jay");
var tom2 = Object.create(cat);

//tom2.like.push("tom");
console.log(tom.like + " " + tom.color);
console.log(tom2.like + " " + tom2.color);
/**********结果***********/
fish,bird,jay black
fish,bird,jay white

寄生继承

function inheritance(cat) {
    var clone = Object.create(cat);
    clone.say = function() {
        console.log("QAQ");
        // console.log(this.color); 虽然这样确实可以输出,但是就太耦合失去函数包装的意义了
    }
    return clone;
}
var cat = {
    color: "black",
    like: ["fish", "bird"]
};

var tom = Object.create(cat);
console.log(tom.like);
tom = inheritance(tom);
tom.say();

/*******运行结果*********/
[ 'fish', 'bird' ]
QAQ

其实只是函数只是实现了对对象的功能增强.

组合寄生继承

function inherit(son, father) {
    var prototype = Object.create(father.prototype); //创建父对象的原型
    prototype.constructor = son; //次原型指向子对象
    son.prototype = prototype; //子对象的构造函数改为刚刚创建的函数
}

function cat(name) {
    this.name = name;
    this.like = ['fish', 'bird'];
}
cat.prototype.sayname = function() {
    console.log(this.name);
}

function blackcat(name, age) {
    cat.call(this, name);
    this.age = age;
}
inherit(blackcat, cat);
blackcat.prototype.sayage = function() {
    console.log(this.age);
}
var tom = new blackcat("tom", 2);
tom.sayage();
tom.sayname();
console.log(tom.like);
/*******输出结果**********/
2
tom
[ 'fish', 'bird' ]

此方案可以解决组合继承方式重复调用构造函数的bug(父级对象调用一次创建变量,子级对象又调用一次覆盖父级对象变量)