[duyi]171130 继承、枚举、克隆

tips1.继承方式

  1. 1原始继承方式
Event.prototype.say = function() {
    console.log('say');
}

function Event() {
    var a = 10;
    this.type = 'function';
}

Http.prototype = new Event();

function Http() {

}
var oHttp = new Http();
console.log(oHttp.type);


 - 过多的继承无用的属性
  1. 2.借用构造函数
function Person(name, age, sex) {
   this.name = name;
   this.age = age;
   this.sex = sex;
}
var oPerson = new Person();
function Student(name, age, sex, grade, clas) {
   // creative this {} 

   // this.name = name;
   // this.age = age;
   // this.sex = sex;
   Person.call(this, name, age, sex); 
   this.grade = grade;
   this.clas = clas;
   //return this;
}
var oStudent = new Student('yp', 18, 'man', 3, 3);

 - 不能继承借用构造函数的原型
 - 每次构造函数都要多走一个函数
  1. 3共享原型
Event.prototype.say = function() {
    console.log('say');
}
Event.prototype.show = function(){
}
function Event() {
    var a = 10;
    this.type = 'function';
    this.show();
}

Http.prototype = Event.prototype;
Http.prototype.show = function(){
}
function Http() {

}
var oHttp = new Http();
console.log(oHttp.type);

 - 虽然不会继承多余属性
 - 但是由于对象是引用值,因此下游改变会影响上游
  1. 4圣杯模式
Father.prototype.lastName = 'Deng';

function Father() {

}

function Son() {
   this.girlFriend = 'ab';

}
Event.prototype.say = function() {}

function Event() {

}

function Http() {
   this.status = 200;
}
var inherit = (function() {
   var Cache = function() {
       //生成闭包
   };
   return function(Target, Origin) {
       Cache.prototype = Origin.prototype;
       Target.prototype = new Cache();
       Target.prototype.constructor = Target;
       Target.prototype.uber = Origin;
   }
})();
inherit(Son, Father);
inherit(Http, Event);

这里写图片描述


tips2.命名空间

  • 管理变量, 防止污染全局, 适用于模块化开发
  • 命名空间已经不使用
  • 防止代码污染 有效方式: 立即执行函数, 封闭作用域
(function() {
     var message = 'red div';
     topDiv.onclick = function() {
         alert(message);
     }
})();

这里写图片描述


tips3.链式调用

var mrDeng = {
    health: 100,
    smoke: function() {
        this.health -= 5;
        return this;
    }, 
    drink: function() {
        this.health -= 4;
        return this;
    },
    perm: function() {
        this.health += 2;
        return this;
    }
}
mrDeng.smoke().drink().perm(); //链式调用
// 返回值.drink().perm();
// 我们返回一个对象,刷新后的mrDeng继续调用后面的方法 return (新的)this--(mrDeng)
  • mrDeng是一个对象,然后链式的执行方法,其中的原理很简单,就是执行完一个方法之后就返回对象本身
 var prop = 'wife1';
 var mrDeng = {
     wife1: 'xiao 1',
     wife2: 'xiao 2',
     wife3: 'xiao 3',
     wife4: 'xiao 4',
     sayWife: function() {
         document.write('my wife' + this.prop);
     }
 };
 mrDeng.sayWife();
  • 输出结果是【my wifeundefined】
  • this.prop 相当于 this[‘prop’]
  • 对象内没有这个属性字符串
  • this[prop]
var prop = 'wife1';
var mrDeng = {
    wife1: 'xiao liu',
    wife2: 'xiao wang',
    wife3: 'xiao lang',
    wife4: 'xiao gei',
    saywife: function(num) {
        // document.write('我的老婆是' + this['wife' + num]);
        //mrDeng.wife2 -> mrDeng['wife2']   this.wife2 -> this['wife2']
        document.write('我的老婆是' + this.prop);
        document.write('我的老婆是' + this['prop']);
        //this.prop -> this['prop'] 字符串prop和变量prop
        document.write('我的老婆是' + this[prop]); 
    }
}
mrDeng.saywife(3);

tips4.对象枚举

  • for _ in _ (枚举遍历所有属性)
var mrDeng = {
        son: 'mini Deng',
        wife: 'miss liu',
        age: 40,
        sex: 'male',
        __proto__: {
            company: 'DUYI',
            car: 'oooo'
        }
    }
for (var prop in mrDeng) {
    console.log(prop);
    console.log(prop, mrDeng[prop]);
}

这里写图片描述

  • hasOwnProperty (判断是否是自己的属性)
var mrDeng = {
    son: 'mini Deng',
    wife: 'miss liu',
    age: 40,
    sex: 'male',
    __proto__: {
        company: 'DUYI',
        car: 'oooo'
    }
}
for (var prop in mrDeng) {
console.log(prop, mrDeng[prop], mrDeng.hasOwnProperty(prop));

这里写图片描述

  • in(判断是否是自己以及原型链中的属性)
var mrDeng = {
    son: 'mini Deng',
    wife: 'miss liu',
    age: 40,
    sex: 'male',
    __proto__: {
        company: 'DUYI',
        car: 'oooo'
    }
}
for (var prop in mrDeng) {
    console.log(prop in mrDeng);
}

这里写图片描述

  • instanceof(看一下A的原型链上有没有B的原型)
function A() {

}
var oA = new A();
console.log(oA instanceof A);

var b = [];

console.log(b.constructor);
console.log(b instanceof Array);
console.log(b instanceof Object);
// A(对象的原型链上) instanceof(有没有)  B(构造函数的原型)  
// 看一下A的原型链上有没有B的原型
// 跨域不适用

这里写图片描述

  • caller & callee
  • caller(调用者)返回一个函数的引用,这个函数调用了当前的函数;
  • callee放回正在执行的函数本身的引用,它是arguments的一个属性
var num = (function(n) {
    if (n == 1 || n == 2) {
        return 1;
    }
    return arguments.callee(n - 1) + arguments.callee(n - 2);
})(7);
  • 递归

这里写图片描述


tips5.克隆

  • 浅层克隆
var mrChen = {
    name: 'cst',
    age: 18,
    sex: 'man',
    girlFriend: {
        name: 'zly',
        age: 28
    },
    height: 183
}
var obj = {};

function clone(target, origin) {
    for (var prop in origin) {
        target[prop] = origin[prop];
    }
}
clone(obj, mrChen);
obj.girlFriend.name = 'zzt';

//这种克隆存在弊端。原始对象的引用值地址给了克隆体,克隆体改变值会影响原始值
  • 深层克隆

    1.判断是不是原始值,如果是引用值,地址给了你,大家都可以改变 
    2.判断是数组还是对象 
    3.如果是建立在相应的数组或对象 反之直接copy 
    4.如果上述建立了数组或对象,对此我们再次深度拷贝

var mrChen = {
    name: 'cst',
    age: 18,
    sex: 'man',
    girlFriend: {
        name: 'zly',
        age: 28
    },
    height: 183
}
var obj = {};

function clone(target, origin) {
    var str = '[object Array]';  //判断是不是数组的关键字
    var toString = Object.prototype.toString; //如果经常使用某一个方法可以使用简单的变量名去储存
    for (var prop in origin) {
        if (origin.hasOwnProperty(prop)) {
        //是不是自己的属性,不想要原型链上的属性
            if (typeof origin[prop] == 'object') {
            //判断这个值是不是对象或数组
                if (toString.call(origin[prop]) === str) {
                //判断是不是数组
                    target[prop] = [];
                    //你是数组,先给你一个数组的外壳,你是引用值不能把地址直接给你,
                    //我用递归把你属性中属性值是数组、对象的属性再次循环判断
                    //将其中的值赋给克隆体,给外壳加料
                } else {
                    target[prop] = {};//后面把值给他
                }
                clone(target[prop], origin[prop]);
                //递归,将属性中对象的值赋给它
            } else {
                target[prop] = origin[prop]//原始值直接赋值
            }

        }
    }
}
clone(obj, mrChen);
obj.girlFriend.name = 'zzh';
  • 纯函数(pure function):纯函数是指不依赖于且不改变它作用域之外的变量状态的函数。
         也就是说,纯函数的返回值只由它调用时的参数决定  它的执行不依赖于系统的状态(比如:何时、何处调用它——译者注)。


----------------------------------------------------------------------------------------------------------------------------------------



----------------------------------------------------------------------------------------------------------------------------------------


  • 判断一个对象是不是数组的方法
var a = [];
1. Object.prototype.toString.call(a);
2. a instanceof Array;
3. a.consturctor

这里写图片描述

tips6.this

  • 普通函数
function test(a) {
    //AO {a:44, b:undefined, c:function(){}, this:window}
    console.log(this);
    //没有任何显示调用,那么this就是window,可以输出
    var b = 10;

    function c() {

    }
    var c = 20;
}
test(44); //window

这里写图片描述

  • 一个对象的属性
 var obj = {
     show: function test(a) {
         //AO {a:44, b:undefined, c:function(){}, this:obj}
         console.log(this);
         var b = 10;

         function c() {

         }
         var c = 20;
     },
     name: 'yp'
 }

 obj.show(44); //obj

这里写图片描述

  • 构造函数
function test(a) {
    //AO {a:44, b:undefined, c:function(){}, this:Object.create(test.prototype)}
    //var this = Object.create(test.prototype);
    console.log(this);
    var b = 10;

    function c() {

    }
    var c = 20;
}
var b = new test(); //Object.create(test.prototype)
//this 是个 对象  原型是test.prototype

这里写图片描述


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值