JS原型

本文详细介绍了JS原型的概念,包括如何通过_prototype_进行属性的增删改查,原型链的工作原理,以及call和apply方法的作用和区别。重点讨论了this的指向和对象的构造函数。此外,还提到了通过Object.create(null)创建无原型对象的特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JS原型(指向的延伸)

                                                        ----如果自己的类中没有那么它就会沿着 _prototype_的索引去找,也就是找原型所指向的对象

1.定义:原型是function对象的一个属性,它定义了构造函数制造出的对象的公共祖先。通过该构造函数产生的对象,可以继承该原型的属性和方法,原型也是对象。

2.利用原型特点和概念,可以提取共有属性。

3.对象如何查看原型->隐式属性

  

 //Person.prototype       -原型
 //Person.prototype ={}   -是祖先
 Person.prototype.nationality = "Chinese";
 Person.prototype.say=function () {
    console.log("I am Chinese");
 }
function Person(){
}
var zhangwuji = new Person();
var huoyuanjia = new Person();
console.log(huoyuanjia.nationality);
zhangwuji.say();

 //Person.prototype       -原型 是系统自带的 在函数出生时就已经被定义好了,它原本就是个对象

即: Person.prototype ={},可以将其理解为一个空的对象,他就相当于Person 这个构造函数构造出的一个爹
 

Chinese

I am Chinese

原型的增删改查

增加和修改: Ojbect.prototype.属性 = 属性值;

查看: Ojbect.prototype.属性名;

删除:delete Ojbect.prototype.属性名;这里删除要删除原型中的属性,不能说删除了一个实例中的属性就说删除了对象原型的属性。

简写形式

// Person.prototype.nationality = "Chinese";
 // Person.prototype.aaa;
 // Person.prototype.bbb;
 // Person.prototype.say=function () {
 // }
function Person(){
}
 Person.prototype ={
     nationality:"Chinese",
     say:function() {
         console.log("I am Chinese");
     }
 }
 var a = new Person();
    a.say();

Constructor 可以被修改

function Person(){
}

Car.prototype ={
    construct:Person
}

function Car(){
}
 var car = new Car();
console.log(car.construct);
  • function Person(){ }

系统发生了如下变化

function Person(){
    //var this  ={
    //     _proto_:Person.prototype
    //}
}

Car.prototype ={
    construct:Person
}

function Car(){
}
 var car = new Car();
console.log(car.construct);

如果去访问对象中的某个属性的时候,当这个对象中不存在这个属性,那么它就会根据这个对象中 _proto_ 的引用去找。所以这里如上打印的结果是被修改了,所以打印出的为

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

>sunny

以上可以分三步理解:

 Person.prototype = {name:'sunny'};
_proto_:Person.prototype;
//在这里声明时,其实_proto_:Person.prototype 已经换了存储地址了
 Person.prototype = {name:'cherry'};

所以person 只能拿到原来的name 所以结果为 sunny

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

->cherry

注意:通过Object.create(null);创建的对象没有原型:

 var o =  Object.create(null);
    console.log(o.prototype);

>undefined

原型链

    原型链的核心就是依赖对象的_proto_的指向,当自身不存在的属性时,就一层层的扒出创建对象的构造函数,直至到Object时,就没有_proto_指向了。

Grand.prototype.lastName =  "Deng";
function Grand() {

}
var grand = new Grand();
Father.prototype = grand;
function Father(){
    this.name = "xuming";
}
var  father = new Father();

Son.prototype = father;
function Son() {
    this.hobbit = "smoke";
}
var son  = new Son();
console.log(son.name);
console.log(Grand.prototype.__proto__);

Person.prototype={
    name:"a",
    sayName: function () {
        console.log(this.name);
    }
}
function Person() {
    this.name="b";
}
var person  = new Person();
person.sayName();
Person.prototype.sayName();

 >b

  >a

谁调用this指的就是谁

Person.prototype={
    money:100
}
function Person() {
    this.eat = function () {
       this.money--;
    }
}
var person  = new Person();
person.eat();
console.log(person.money);
console.log(Person.prototype.money);

>99

>100

call/apply:


作用:改变this指向。

区别,后面传的参数形式不同。 

  function test() {
        console.log("执行!")
    }
    test.call(); 相当于 test(),因为 test()会调用test.call();

>执行!

function Person(name,age){
this.name = name;
this.age = age;
}
var person =  new Person("小王",23);
var obj = {
}
Person.call(obj,"李元霸",22);

这里的call 改变了this的指向 

function Person(name,age){
// this = obj; 这里的this 由原来的window 对象,改变为obj 对象
this.name = name;
this.age = age;
}
var person =  new Person("小王",23);
var obj = {
}
Person.call(obj,"李元霸",22);
function Person(name,age){
// this = obj;
this.name = name;
this.age = age;
}
function Student(name,age,sex,tel,grade) {
    //var this = {name:"",age:"",sex:""}
  Person.call(this,name,age,sex);
  this.tel = tel;
  this.grade = grade;
}
var student =  new Student("sunny",23,'male',139,2017);

当执行new Student() 时 此时 执行Person.call(this,name,age,sex) 那么这里的this 就是指Person

 

function Wheel(wheelSize,style) {
    this.style = style;
    this.wheelSize = wheelSize;
}

function Sit(c,sitColor) {
    this.c = c;
    this.sitColor = sitColor;
}

function Model(hegiht,width,length) {
    this.height = hegiht;
    this.width = width;
    this.length = length;
}

function Car(wheelSize,style,c,sitColor,hegiht,width,length) {
    Wheel.call(this,wheelSize,style);
    Sit.call(this,c,sitColor);
    Model.call(this,hegiht,width,length);
}

var car = new Car(100,"雨胎","comfortable","blue",400,300,200);

 

apply第一位也是传this 但是后面只能传一个参数,那么如果多参就要用数组

function Wheel(wheelSize,style) {
    this.style = style;
    this.wheelSize = wheelSize;
}

function Sit(c,sitColor) {
    this.c = c;
    this.sitColor = sitColor;
}

function Model(hegiht,width,length) {
    this.height = hegiht;
    this.width = width;
    this.length = length;
}

function Car(wheelSize,style,c,sitColor,hegiht,width,length) {
    Wheel.apply(this,[wheelSize,style]);
    Sit.call(this,c,sitColor);
    Model.call(this,hegiht,width,length);
}

var car = new Car(1002,"越野","comfortable","red",400,300,200);

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

apply 需要传一个arguments 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值