不清楚JavaScript中的原型?看完这篇你就懂了

前言

今天我们要来聊的内容是JavaScript中的原型和原型链。原型是JS中重要的一部分,同时当我们了解原型的概念,学会原型时,也能使我们编程减少代码重复,大大提高我们编程的效率。那么继续往下看吧!

正文

  • 1.原型是函数上的一个属性,它定义了构造函数制造的对象的公共祖先。

看到这句话可能有点懵,那让我们通过一段代码来解释吧

js 复制代码
function Person(){
    this.name = 'tom' 
}
let p = new Person()

console.log(p);

这段代码打印结果是{ name: 'tom' }。这是为什么呢?因为当我们用 new 关键字来创建一个对象实例时,它会调用构造函数并初始化该对象。在这个构造函数中,通过 this.name = 'tom' 给对象添加了一个 name 属性,并将其值设为 'tom'。因此,当我们打印这个对象时,会显示 { name: 'tom' }

js 复制代码
Person.prototype.lastName = 'zhu'
Person.prototype.say = function(){
    console.log('hello');
}
function Person(){
    this.name = 'tao'
}
let p1 = new Person() // 隐式具有  lastName  say 
 

p1.say()

在这一段代码中我们在构造函数的部分并未添加lastname属性,可是当我们查找这个属性时是能打印出来的,同时p1 可以访问通过原型继承的 lastName 属性和 say 方法。当调用 p1.say() 时,它会执行原型上的 say 方法,并打印 'hello'

那么原型能有什么作用呢?

  • 1.构造函数 new 出来的对象会 隐式继承到 构造函数原型上的属性
js 复制代码
// 在构造函数之外为 Car 添加原型属性
Car.prototype.name = 'su7';
Car.prototype.lang = '5000';
Car.prototype.height = '1400';

function Car(color, owner) {
    this.color = color;
    this.owner = owner;
}

let tian = new Car('black', 'tiantian');
let xuan = new Car('green', 'xuanxuan');

console.log(tian.name); // 输出: 'su7

在这段代码中我们用了构造函数Car,它接受 colorowner 作为参数,并将它们分别赋值给新创建的实例的 colorowner 属性。然后我们又创建了两个不同的实例对象。我们通过 Car 构造函数的原型添加了 name 属性,这样所有 Car 实例都可以访问它。所以 console.log(tian.name) 输出 'su7'。 这样做的优点是所有 Car 实例对象共享相同的属性,而不需要在每个实例中单独定义它们。提高了我们的代码效率。

  • 2.实例对象可以修改显示继承到的属性,但是无法修改隐式继承到的属性(原型上的)
js 复制代码
Car.prototype.product = 'xiaomi'
function Car(){
    this.name = 'su7'
}

let car = new Car()

car.name = '保时捷'
car.product = 'HUAWEI'

// car.nickname = '小红'

// delete car.product
// delete Car.prototype.product

console.log(car.product)

在这段代码中,我们修改了 car 实例对象的 name 属性为 '保时捷',并添加了一个新的 product 属性 'HUAWEI'。因为实例对象上已经存在一个名为 product 的属性(被赋值为 'xiaomi'),所以这个赋值操作会覆盖原型上的 product 属性。由于实例对象上已经有一个 product 的属性,它会覆盖原型上的同名属性。所以最后的打印结果是 'HUAWEI'

在这一点中我们同时还需要注意这两点:

1.实例对象无法给原型新增属性

2.实例对象无法删除原型上的属性

js 复制代码
Car.prototype.product = 'xiaomi'
function Car(){
    this.name = 'su7'
}
let car = new Car()

delete car.product
// delete Car.prototype.product

在这段代码中如果执行delete car.product,那么最后打印的product还是xiaomi,这是因为果这个属性来自原型,那么原型上的属性仍然存在,对实例对象是不可见的。

  • 3.对象的隐式原型 === 创造它的构造函数的显式原型
js 复制代码
function Person(){

}
let p = new Person()

console.log(Person.prototype);  // 函数的原型  显示原型
console.log(p._proto._);  //p._proto._  对象的原型  隐式原型

// Person.prototype === p._proto._

函数的原型(显示原型) :在 JavaScript 中,每个函数都有一个特殊的属性 prototype,它指向一个对象,称为函数的原型。这个原型对象是在函数定义时自动创建的。

对象的原型(隐式原型)console.log(p.__proto__);这行代码打印了 p 实例对象的原型,也称为隐式原型。`

在 JavaScript 中,所有通过构造函数创建的实例对象都会继承自该构造函数的原型。因此,Person.prototype === p.__proto__ 表达了函数的原型和对象的原型之间的关系。而且js引擎在查找属性时,会先查找对象显示具有的属性,找不到,再查找对象的隐式原型(proto)

总结

在这篇文章中我们这篇文章中介绍了什么是原型以及原型的一些特点。

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

实例对象会通过自己的隐式原型去继承构造函数显示原型上的属性和方法

今天的内容就到这里啦,如果这篇文章对你们有帮助,辛苦你们把小赞点起来^_^

相关推荐
cwj&xyp27 分钟前
Python(二)str、list、tuple、dict、set
前端·python·算法
dlnu201525062229 分钟前
ssr实现方案
前端·javascript·ssr
古木201934 分钟前
前端面试宝典
前端·面试·职场和发展
轻口味2 小时前
命名空间与模块化概述
开发语言·前端·javascript
前端小小王3 小时前
React Hooks
前端·javascript·react.js
迷途小码农零零发3 小时前
react中使用ResizeObserver来观察元素的size变化
前端·javascript·react.js
娃哈哈哈哈呀3 小时前
vue中的css深度选择器v-deep 配合!important
前端·css·vue.js
旭东怪4 小时前
EasyPoi 使用$fe:模板语法生成Word动态行
java·前端·word
ekskef_sef5 小时前
32岁前端干了8年,是继续做前端开发,还是转其它工作
前端