原型与原型链JS

本文详细解析JavaScript中的原型机制,包括原型的定义、应用、增删改查,原型链的构成以及Object.create的使用。同时介绍了call和apply方法如何改变函数的this指向。
摘要由CSDN通过智能技术生成

原型与原型链

一:原型

1.定义:原型是Funtion对象中的一个属性,它定义了构造函数制造出的对象的共同祖先。通过该构造函数产生的对象,可以继承该原型的属性和方法。原型也是对象。
//Person.prototype ----原型   一个对象   当一个函数被定义时它就存在,自身带的属性
//Person.prototype = {} 是祖先
Person.prototype.Firstname = "li"
Person.prototypr.Lastname = "Am"
//或者
//Person.prototype = {
//  Firstname: "li",
//  Lastname:"Am"
//}
function Person (Lastname) {
    this.Lastname = Lastname;
}
var person = new Person(Bm);
var person1 = new Person(Cm);
console.log(person.Fiestname,person.Lastname);
//输出“li Bm”,虽然 new Person()之中没有name属性,但是它会从它的Person.prototype(原型)中继承,如果 new Person()中有该属性那么就会用自己的属性而不会用原型的属性。
console.log(person.Firstname,person.Lastname);//也是输出“li Cm”,以为它和person1用的是同一个原型;
2.应用:可以利用原型提取公共属性
  • 比如上面中的Firstname就相当与公共属性,在原型中增加该属性可以减少耦合;

3.增删改查(通过子代)
  1. 增删改

    • 基本上只能通过函数的原型来修改(Person.protoype.Firstname = "wang").

    • 通过new的对象来修改基本上不可能

    • 只有被继承时才会显示

4.prototye.constructor(构造器)
Person.prototype = {
    //看似为空,其实其中有两个隐式属性,为系统自设;
    /*constructor:Person(),    是构造出这个原型的函数---可以手动更改
    _proto_:object           详下一个*/
}
function Noething (){
    
}
Person.prototype.constructor = Noething//此时Person.prototype.constructor 为noething。
5.prototype.proto
function Car () {
    /*new 的全过程 --- 隐式过程
        var this = {
            __proto__:Car.prototype     ----  相当于起到联接原型的作用
        };
        .....(执行函数内容)
        return this*/
}
var car = new Car();

二:原型链

  • 通过—proto—来联接原型,使其形成链

Grand.prototype.Lastname = "li";
function Grand () {
    
}
var grand = new Grand();
​
Father.prototype = grand;
function Father() {
    this.name = "Am";
    this.money = "20W";
    this.key = {
        key1:"200"
    };
}
var father = new Father();
​
Son.prototype = father;
function Son () {
    this.name = "Bm";
    this.age = 18;
}
var son = new Son();
//假如出现没有的属性会一层一层的往上寻找  son->Son.prototype.__proto__(father)->Father.prototype.__proto__(grand)->Grand.prototype.__proto__(Object)->Object.prototype.__proto__(null)  ————终端
console.log(son.name)//输出“Bm”
console.log(son.money)//输出"20W"
console.log(son.Lastname)//输出“li”
​
//增删改查   ---其实与原型差不多
son.Lastname = "wu"//这里是son本身加了一个属性,而非将Grand的Lastname修改为"wu"----增删改一样也(换句话就是通过子代修改父代基本上不能实现)
​
//特例-----针对于引用值(方法的修改,而不是覆盖/赋值的修改)
son.key.key2 = "300"//这里就可以将Father.key添加一个key2 = "300"的属性,而son并没有该属性,因为对于调用应用值它操作的是它直接(简而言之就是son.key.key2这里只是在操做key这个对象,son.key是调用了key)
Man.prototype = {
    name: "Am",
    height: 100,
    say: function (){
        console.log(this.name);
    }
}
function Man (){
    this.name = "Bm";
    this.eat = function(){
        this.height ++;
    }
}
var man = new Man()
man.say();//输出“Bm”,方法中的this指向---谁调用的就指向谁
man.eat();//man中会添加一个height属性并且值为101,首先调用eat()后会执行this.height ++,因为man自身没有height所以就会继承原型的height并且++后添加到man中

三:Objec.create()所创建的对象

// var obj = Object.create(原型) --------create()括号中只能填“对象”或者"null"
var obj = {
    name: "li",
    age: 19
}
var obj1 = Object.create(obj);//此时obj1的原型为obj
​
​
//因为create()可以填null,所以导致其创建出的对象可能没有原型
var obj2 = Object.create(null);
//此时obj2没有原型;
  • 由上所得:只是绝大多数对象最终会继承自Object.prototype

四:call/play

  • 作用:改变this指向

function Person (name, age) {
    this.name = name;
    this.age = age;
}
var person = new Person()
var obj = {
    
}
Person.call(obj,"wu",20);//改变this指向,相当于在Person函数中顶部新增(this = obj),而后面两个是传入的参数
//实际上: Person() === person.call()
//此时;obj = {
//      name: "wu",
//      age: 20
//}
function Person (age,name){
    this.name = name;
    this.age = age;
}
/*假如也有一个构造函数需要实现的功能包括了上面的构造函数,如:
function Student (age,name,socor) {
    this.name = name;
    this.age = age;
    this.socor = socor;
}*/
//那么就可以用call的方法简化代码
function Student (age,name,socor) {
    Person.call(this,age,name);
    this.socor = socor;
}
var student = new Student;
  • apply其实与call差不多,只有一点区别

    • 传参方式的不同

      1. call:需要把实参按照形参的个数传进去

      2. apply:传入的是一个arguments(实参列表)----数组

    function Student (age,name,socor) {
        Person.apply(this,[age,name]);
        this.socor = socor;
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值