关于JavaScript原型、call、apply的知识总结


前言

这篇笔记主要是理解原型、原型链、call()、apply(),如何基础的使用。也借鉴了其他博客,总结了以下知识。

一、原型是什么?

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

普通函数没有prototype,只有__proto__
函数对象中既有prototype也有__proto__

二、原型的特点

1、继承原型的属性和方法

代码如下(示例):这里的person里面并没有LastName、say属性和方法,但是通过person.LastName/say可以得到值,说明person继承了原型上的属性和方法

<script>
   Person.prototype.LastName="tang";
   Person.prototype.say=function (){
       console.log('hehe');
   }
   function Person(name,age,sex){
       this.name=name;
       this.age=age;
       this.sex=sex;
   }
   var person=new Person('na',18,'female');
</script>

运行结果

2、提取共有属性

代码如下(示例):这里不管是car还是car1都有height和CarName属性,因为它们都继承于同一个原型,根据这个特点可以实现共有属性

<script>
    Car.prototype.height=1000;
    Car.prototype.CarName='BMW';
    function Car(color,owner){
        this.color=color;
        this.owner=owner;
    }
    var car=new Car('red','tn');
    var car2=new Car('pink','xz');
</script>

该处使用的url网络请求的数据。

3、如何查看隐式属性__proto__

每个对象都有一个隐藏的属性–> __proto __,这个属性引用的是创建该对象的函数的prototype,

<script>
//函数也是一种对象
    function Obj(){}
    var obj=new Obj()
    console.log(obj.__proto__);
</script>

在这里插入图片描述

console.log(Obj.prototype)

在这里插入图片描述
可以看出obj.__proto__和Obj.prototype里面的内容一样的,是因为obj是被Obj函数创建出来的,所以Obj.prototype===obj.__proto __

则每个对象都有__proto __隐藏属性,它都指向创建该对象的函数的prototype

4、如何查看对象的构造函数constructor

  constructor是每个示例对象都拥有的属性,b.constructor指向B
  所以下面的例子obj.constructor打印的是Obj()
<script>
    function Obj(){}
    var obj=new Obj()
    console.log(obj.constructor);
</script>

在这里插入图片描述

5、如何构造原型链

访问对象的属性是最开始是在本身里面查找,若是没有再沿着__proto__ 向上面查找。把原型连成一个链,遵循就近法则。

就以下面的例子来说:
son.name 得到的结果是tn,本来son里面就没有name这个属性,但是沿着__ proto __的方向,最开始找到了father,但是Father上并没有name属性,再沿着father的__proto __ 找到了Grand,Grand原型上有name属性,因此,son.name=tn

<script>
    Grand.prototype.name='tn'
    function Grand(){
 //   var this={__proto__:Grand.prototype}
    }
    var grand=new Grand();
    Father.prototype=grand;

    function Father(){
    //var this={__proto__:Father.prototype}
        this.sex='male'
    }
    var father=new Father();
    Son.prototype=father;
    function Son(){
   //var this={__proto__:Son.prototype}
   }
    var son=new Son();
</script>

三、call()和apply()

1、call()

用法:obj1.call(obj2,argument1,argument2),obj1就是this的指向,
      后面的是参数,通俗的来讲,就是把obj1的方法放在obj2上使用。
      
作用:改变this的指向
<script>
  function Person(name,age){
    //因为person.call(obj)
    //因此  this指向obj
    this.name=name;
    this.age=age;
  }
  var person=new Person('tn',18);
  var obj={}
  //         指向谁 参数 参数
  Person.call(obj,'xz',20)
</script>

在这里插入图片描述

2、apply()

 用法:obj1.apply(obj2,[argument1,argument2])  参数列表必须是数组
 作用:改变this指向
<script>
  function Person(name,age,sex){
    this.name=name;
    this.age=age;
    this.sex=sex
  }
  function Student(name,age,sex,tel,grade){
    Person.apply(this,[name,age,sex]);
    this.tel=tel;
    this.grade=grade;
  }
  var st=new Student('tn',22,'female',23333343,2019)
</script>

在这里插入图片描述

3、call()和apply()的相同点和区别

    相同点:都改变了this的指向
    不同点:传递参数列表不同
            obj1.apply(obj2,[argument1,argument2])
            obj1.call(obj2,argument1,argument2)

例题

1、关于原型的例题

<script>
    //    proto里面放的是原型  
    //   var this={ 
    //          __proto__:Perdon.Prototype 
    //        } 
        Person.prototype.name='sunny';
        function Person(){};
        var person=new Person;
    Person.prototype.name='cherry';
        console.log(person.name);//打印cherry
    
// 将Person.prototype.name='cherry';放在var person=new Person;的前面
        Person.prototype.name='sunny';
        function Person(){};
       Person.prototype.name='cherry';
        var person=new Person;
        console.log(person.name);//打印cherry
    
    
    Person.prototype.name='sunny';
    function Person(){
        // var this={__proto__:Person.prototype}
    };

    var person=new Person;
    Person.prototype={
        name:'cherry'
    }
    console.log(person.name);//打印sunny
    
//其实这里相当于:prototype.name=suuny
//			    __proto__=prototype.name
//				prtotype.name=cherry
//所以打印出suuny



    // 将 Person.prototype={
    //     name:'cherry'
    // }
    // 放在  var person=new Person;后面
    Person.prototype.name='sunny';
    function Person(){
        // var this={__proto__:Person.prototype}
    };

    var person=new Person;
    Person.prototype={
        name:'cherry'
    }
    console.log(person.name);//打印cherry
//其实这里相当于:prototype.name=suuny
//				 prtotype.name=cherry
//			    __proto__=prototype.name
// 所以打印出cherry

    
</script>

2、关于call()的例题

<script>
  function Wheel(wheelSize,styles){
    this.styles=styles;
    this.wheelSize=wheelSize;
  }
  function Sit(c,sitColor){
    this.c=c;
    this.sitColor=sitColor;
  }
  function Model(height,width,len){
    this.height=height;
    this.width=width;
    this.len=len;
  }
  function Car(wheelSize,styles,c,sitColor,height,width,len){
    Wheel.call(this,wheelSize,styles);
    Sit.call(this,c,sitColor);
    Model.call(this,height,width,len);

  }
  var car=new Car(100,'花里胡哨','真皮','red',1800,1900)
</script>

在这里插入图片描述

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值