面向对象与继承

JavaScript对每个创建的对象都会设置一个原型,指向它的原型对象。
面向对象核心规则:
1.所有的函数对象都有一个原型对象(prototype);
2.所有的对象上都有一个隐式原型(proto)指向创建该对象的构造函数的原型;
3.所有的原型上都有一个constructr指向该原型所在的构造函数本身;
构造函数模式constructor所谓构造函数,就是普通函数,但是内部使用了this变量,对构造函数使用new运算符,就能生成实例,并且this变量会绑定在实例对象上;

function Cat(name,color){
    this.name=name;
    this.color=color;
  }
var cat1 = new Cat("大毛","黄色");
var cat2 = new Cat("二毛","黑色");
  alert(cat1.name); // 大毛
  alert(cat1.color); // 黄色

这时cat1和cat2会自动含有一个constructor属性,指向它们的构造函数

cat1.constructor == Cat

此方法的弊端:如果所执行的方法都是一样的,但都要生成一个实例,就很占内存。
instanceof
验证原型对象与实例对象之间的关系alert(cat1 instanceof Cat); //true
前面(cat1)必须是复杂数据类型
prototype模式
每一个构造函数都有一个prototype属性,指向另一个对象。
这个对象的属性和方法,都会被构造函数的实例继承。
为了解决构造函数占用重复内存,我们将共有的属性和方法放在prototype对象上(公共区域)

Cat.prototype.eat = function(){alert("吃老鼠")};
cat1.eat == cat2.eat//true

prototype模式验证方法
isPrototypeOf()
用来判断某个某个对象的原型与某个实例之间的关系Cat.prototype.isPrototypeOfh(cat1)
hasownProperty()每个对象都有一个hasownproperty()方法,用来判断某一个属性到底是本地属性,还是继承prototype(继承下的)对象的属性;in运算符用来判断实例对象是否含有某个属性,不管是不是本地属性还是继承属性;还可以用来遍历某个对象的所有属性;

for (var key in cat1) {
      alert(`cat1[ ${key}  ]=` + cat1[key]);
}

承构造函数绑定使用call,apply方法将父对象的构造函数绑定在子对象上

function Cat(name,age){
        Animal.call(this,arguments)//继承Animal
        this.name=name;
        this.age=age;
}
pro

totyoe模式如果猫的prototype指向一个Animal实例那么所有猫的实例都能继承Animal了

`Cat.prototype=new Animal();`
//此时的Cat.prototype.constructor==Animal;
cat1明明是用构造函数Cat生成的,因此我们必须手动矫正
Cat.prototype.constructor=Cat;
let cat1=new Cat();
直接继承  Cat.prototype=Animal.prototype;
 Cat.prototype,constructor=Cat;

但是改变Cat原型,Animal的原型也会改变。不可取空对象继承创建一个空的函数对象
var F = function () {};
将该函数对象的原型指向父对象的原型
F.prototype = Parent.prototype;
删除了子对象prototype 对象原先的值,然后赋予一个新值
Child.prototype = new F();
将gnaij改变的constructor指向改回原来的指向
Child.prototype.constructor = Child
拷贝继承

function extend2(Child, Parent) {
            var p = Parent.prototype;
            var c = Child.prototype;
            for (var i in p) {
                c[i] = p[i];
            }
            c.uber = p;
        }
    

拷贝

    let Chinese = {
            nation: "中国",
            bb: [1, 2, 3, 4],
            aa: [{ name: "zs" }]
        }
        let Doctor = {
            career: "医生"
        }

浅拷贝让Doctor继承Chinese

     function copy(p) {
            let c = {};//创建一个空对象(容器)
            for (let i in p) {//in运算符遍历属性与方法
                c[i] = p[i]//一一放入空对象
            }
            return c//返回空对象
        }
        Doctor = copy(Chinese)
        Doctor.bb.push(12)
        console.log(Chinese.bb);//1,2,3,4,12
        console.log(Doctor.bb);//1,2,3,4,12

修改子对象会对父对象产生影响;
深拷贝

function copy2(p, c) {
            var c = c || {};
            for (let i in p) {
                if (typeof p[i] === `object`) {
                    c[i] = (p[i].constructor === Array) ? [] : {}
                    copy2(p[i], c[i])
                } else {
                    c[i] = p[i]
                }
            }
            return c
        }
        Doctor=copy2(Chinese);
        Doctor.bb.push(12)
        alert(Doctor.bb);//1,2,3,4,12
        alert(Chinese.bb);//1,2,3,4

修改子对象不会对父对象产生影响。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值