原型与原型链JS

发布时间:2024年01月14日

原型与原型链

一:原型

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

文章来源:https://blog.csdn.net/2301_79758239/article/details/135554827
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。