欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

180331 原型

程序员文章站 2022-05-08 16:51:01
...
  • 原型是function对象的一个属性,它定义了构造函数制造出的对象的公共祖先。
  • 通过该构造函数产生的对象,可以继承该原型的属性和方法。
  • 原型也是对象。
  • 原型就像是批处理添加水印:预设好的统一处理,有颜色主题不合适的单独设计。

  • 访问对象的属性,如果本身没有,会向原型上面找。

  • 由构造函数创建的对象,有隠式属性this对象。

  • this对象有一个属性 _ proto_ [指针,指向对象的原型]

  • this . _ proto_ = Function.prototype

  • 由构造函数创建的对象的属性[this]的属性[_ proto_]的值等于构造函数的属性[prototype]的值。

  • 这两个指向的值是一个对象,即原型对象。

obj.attributes 
-> 
if(obj.attributes){return obj._proto_.attributes}

原型应用:

CarFactory.prototype.door = 4;
CarFactory.prototype.distance = 0;
CarFactory.prototype.run = function() {
    this.distance += 100;
}
CarFactory.prototype.aurhor = {
        name: 'cst',
        money: 999999
    }
    //提取全部实例的公共特点,添加到远行对象里
    //相当于给每一个实例初始化,添加水印,节约性能

function CarFactory(wheelNum, carColor) {
    this.wheel = wheelNum;
    this.color = carColor;
}
var oCar1 = new CarFactory(3, 'red');
var oCar2 = new CarFactory(5,'yellow');
        oCar1.door = 6;
// 实例本身新增door属性,就不会找原型,也不会影响原型和其他实例
console.log(oCar.door);

delete oCar1.chair; // true 删除不存在的属性

oCar1.author.money = 200;
console.log(oCar2.author.money);   // 改变实例本身属性,还是改变原型属性

[改变原型对象的指向] 和 [改变原型对象内的值]

CarFactory.prototype.door = 4;
var oCar1 = new CarFactory();
CarFactory.prototype = {
    door:6;   //已经创建好的对象不会被新改变的原型影响
}

// this._proto_ --链接-- Function.prototype
// 这两个值对应的是一个对象,过程是F.p把地址给了t._p_
// 当改变了F.p,它会指向一个新的对象,有一个新的地址
// 而t._p_还是以前的地址
// 两个值不是时刻牵引的,是一次性赋给相同地址,之后撒手
// 让F.p等于一个新对象,相当于断开了与t._p_的联系与羁绊
// 让F.p.attributes等于一个新的值,并没有断开两者的联系,
// 因此会出现给F.p赋值新对象不会影响已经创建的对象
// 而给F.p赋值新的属性值,会影响已经创建的对象
// 因为联系还在,f._p_是跟着对象走的
// 两个都是属性名而已,两张入场券,进入同一个地方,这个地方里面存着原型信息
// 要在一张入场券上增加或修改演员,要么把入场券引向别的场次
// 跟对象直接联系的是__proto__,只要看它的值就行了,是保持链接属性更新。
// 还是断开链接,属性不变

var PrototypeSelf = {name:'cst'};
var __proto__Self = PrototypeSelf;
PrototypeSelf = {name:'duyi'};
__Proto__Self.name  // -> cst

练习

Person.prototype.name = 'sunny';

function Person() {}
var oPerson = new Person();
Person.prototype.name = 'cherry';
console.log(oPerson.name); // cherry


//======================================


Person.prototype.name = 'sunny';

function Person() {}
Person.prototype.name = 'cherry';
var oPerson = new Person();
console.log(oPerson.name); // cherry


//======================================


Person.prototype.name = 'sunny';

function Person() {}
var oPerson = new Person();
Person.prototype = {
    name: 'cherry'
};
console.log(oPerson.name); // sunny

//=======================================

Person.prototype.name = 'sunny';

function Person() {}
Person.prototype = {
    name: 'cherry'
};
var oPerson = new Person();
console.log(oPerson.name); // cherry

查询对象构造函数

object.prototype

原型链

GrandFather.prototype.lastName = 'yang';

function GrandFather() {
    this.bike = 1;
}
Father.prototype = new GrandFather();

function Father() {
    this.fortune = {
        money: 999999,
        house: 4
    }
    this.name = 'jaja'
}
Son.prototype = new Father();

function Son() {
    this.name = 'heihei',
        this.age = 20
}

var oSon = new Son();
console.log(oSon.lastName);

oSon.fortune.house += 1;  //访问fortune对象的属性并赋值,改变相同地址的引用值, 相当于改变原型上的属性
oSon.fortune = {};       //将fortune属性指向另一个对象地址,换了一个引用值, 相当于给oSon自己添加属性

var oSon2 = new Son();
console.log(oSon2.fortune.house);   //  5  这个是引用值,后续会受影响  

180331 原型

  • 除(object.create()创建的对象之外),沿着原型链一直向上游查询,找到头都是object.prototype -> {}
  • 函数的原型对象constructor默认指向函数本身,原型对象除了有原型属性外,为了实现继承,还有一个原型链指针proto,该指针指向上一层的原型对象,而上一层的原型对象的结构依然类似,这样利用proto一直指向Object的原型对象上,而Object的原型对象用Object.prototype.proto = null表示原型链的最顶端,如此变形成了javascript的原型链继承,同时也解释了为什么所有的javascript对象都具有Object的基本方法。
    180331 原型

原型方法的重写

如果原型链中上游已经有一个函数,可以在下游重新定义。

改变this指向

function.call(host,num1,num2)
function.apply(host,[num1,num2])

function test(){
    console.log(this);
}
test();   //thiswindow

相当于window.test.call(window);

function.call(调用者)
function Person(name, age) {
    this.name = name;
    this.age = age;
}

function Student(name, age, myClass, myGrade) {
    Person(); // !!没有写出来是谁调用的,都是window调用
    Person.call(this, name, age); // Studnet函数调用Person函数,保证Person函数的参数
} // call(name,age)->Student(name,age)->Student(实参)
// this是当前调用的函数Student
new Student('cst', 18, 2, 4); //构造函数会在内部隠式创建this对象并返回,
//原因是构造函数本身就是用于创建对象并初始化
//构造函数身份象征:new

var numObj = {
    x: 1,
    y: 2
}

function add(a, b) {
    console.log(this.x + a + this.y + b);
}
add(); // NaN
add.call(numObj, 3, 4); // 10

继承

圣杯模式:闭包

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;
    }
})();

180331 原型


防止变量污染

立即执行函数

相关标签: 原型