JavaScript的原型深度讲解,从小白角度出发

原型是 JavaScript 中的一个重要概念,它涉及到对象之间的继承关系和属性的共享。在 JavaScript 中,每个函数都有一个 prototype 属性,这个属性指向一个对象,即该函数的原型。通过构造函数创建的对象实例会继承构造函数的原型上的属性和方法。

原型(显式原型)

定义:原型是函数天生就有的属性(prototype),它定义了构造函数制造出来的对象的公共祖先 ,通过该构造函数创建的对象,可以隐式的继承函数原型上的属性和方法

js 复制代码
    Person.prototype.say = function(){
   console.log('jxb 真好吃');
}
function Person(){
   this.name = '冷少'// this是一个对象
   this.age = 18
}
let p = new Person()
let p2 = new Person()
console.log(p.say==p2.say);   //打印true,拥有公共祖先

可以看到p.say==p2.say是true,利用prototype,构造函数定义出来的对象是一样的。

js 复制代码
Person.prototype.say = function(){ //prototype   函数自带的属性,函数原型,不会添加到Person
   console.log('jxb 真好吃');
}
function Person(){
   this.name = '冷少'// this是一个对象
   this.age = 18
}
let p = new Person()  //实例对象显式的继承了构造函数添加到this上的属性,隐式的继承函数原型上的属性和方法
let p2 = new Person()
p.say()//打印console.log(p);里面没有say,但是可以用p来调用
console.log(p);

实例对象显式的继承了构造函数添加到this上的属性,隐式的继承函数原型上的属性和方法,所有无法打印p,只有this定义的属性。

意义:可以提取公有属性,简化代码执行

js 复制代码
Car.prototype = {
    name:'BMW',
    long:4900,
    height:1400
}

function Car(ower,color){
    // this.name = 'BMW'
    // this.long = 4900
    // this.height = 1400
    this.ower = ower
    this.color = color
}

 let car = new Car('李总','red')
let car2 = new Car('戴总','pink')

代替了this,简化了代码,用node打印看不到,浏览器可以看到

原型上的属性修改只能原型自己操作,实例对象无权修改

js 复制代码
  Car.prototype.name = 'BMW'
  Car.prototype.long = 4900   
  Car.prototype.height = 1400
function Car(ower,color){
    this.ower = ower
    this.color = color
}

 let car = new Car('李总','red')
let car2 = new Car('戴总','pink')//实例对象
 car.name = '奔驰'
//  delete Car.prototype.name
 delete car.name
console.log(car);
console.log(Car.prototype.name);

第11行代码无法修改原型定义的name第13行代码无法删除原型定义的name,12行代码才能删除。

对象原型(隐式原型)

实例对象的隐式原型 == 构造函数的显式原型

js 复制代码
    function Bus(){
    }
    function Car(){
}
let car = new Car()
// constructor 构造器属性,用于记录对象是由谁创建的
console.log(car.constructor); 

这段代码我们会发现car是Car创造的

再如果我们修改一下代码

js 复制代码
<script>
    function Bus(){

    }
    Car.prototype ={  //  实例对象上的constructor 为什么因为这个改成了Bus
        constructor :Bus  //看看有没有这段代码时的con
    }
    function Car(){

}
let car = new Car()//
// constructor 构造器属性,用于记录对象是由谁创建的
console.log(car.constructor);

可以发现

Car被修改成了Bus,这说明构造函数的显式原型和实例对象的隐式原型肯定有关系,所以实例对象的隐式原型 == 构造函数的显式原型。

new

  1. 创建this对象
  2. 执行构造函数中的逻辑
  3. 让this的隐式原型==构造函数的显式原型
  4. 返回这个this对象

用一段代码解释new的这些作用

js 复制代码
    Person.prototype.say = function(){
        console.log('hello');
    }
    function Person(){
        this.name  ='袁总'
        this.age = 18

      //使用new后创建一个this对象
        // var  this={
        //    name :'袁总',
        //    age:18,
        //    __proto__:Person.prototype   让this的隐式原型==构造函数的显式原型
        // }
        // return this
    }
    let p = new Person()
    p.say()

原型链

顺着对象的隐式原型不断地向上查找上一级的隐式原型,直到找到目标或者null,这种查找关系,叫做原型链

js 复制代码
function Foo(){}
    let foo = new Foo()
  //下面是查找规律
foo.__proto__ === Foo.prototype  //实例对象隐式原型等于构造函数显式原型
Foo.prototype.__proto__ === Object.prototype
Object.prototype.__proto__ ===null

console.log(foo.toString());

这段代码会显示如下内容

在 Object.prototype找到了foo.toString()

网易面试题:所有的对象身上都有隐式原型?

绝大多数有,有的没有,如下就没有隐式原型

但是可以通过继承属性,这样会变成隐式原型

总结起来,原型和原型链是 JavaScript 中非常重要的概念,它们提供了一种灵活的方式来实现对象之间的继承和共享属性和方法。深入理解原型和原型链对于 JavaScript 开发者来说是非常重要的,它能够帮助我们更好地利用 JavaScript 的特性,编写出高效和可维护的代码。

相关推荐
丁总学Java3 分钟前
/src/utils/request.ts:axios 请求封装,适用于需要统一处理请求和响应的场景
开发语言·javascript·ecmascript
m0_749317529 分钟前
VUE学习
前端·javascript·vue.js·学习
16年上任的CTO13 分钟前
一文大白话讲清楚ES6关于函数的扩展
前端·javascript·ecmascript·es6·es6函数扩展
yuehua_zhang33 分钟前
uni app 写的 小游戏,文字拼图?文字拼写?不知道叫啥
前端·javascript·uni-app
weixin_4721835433 分钟前
uniapp使用sm4加密
前端·javascript·uni-app
林涧泣34 分钟前
【Uniapp-Vue3】watch和watchEffect监听的使用
前端·vue.js·uni-app
SimonLiu00936 分钟前
React Native 项目 Error: EMFILE: too many open files, watch
javascript·react native·react.js
xinglee42 分钟前
如何实现优雅的删除动画
前端·javascript·面试
远洋录1 小时前
WebSocket 安全实践:从认证到加密
前端·人工智能·react
贩卖纯净水.1 小时前
JS进阶--JS听到了不灭的回响
java·前端·javascript