【个人笔记js的原型理解】

这篇具有很好参考价值的文章主要介绍了【个人笔记js的原型理解】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在 JavaScript 中,最常见的新建一个对象的方式就是使用花括号的方式。然后使用’ . '的方式往里面添加属性和方法。可见以下代码:

let animal = {};
animal.name = 'Leo';
animal.energe = 10;

animal.eat = function (amount) {
    console.log(`${this.name} is eating.`)
    this.energe += amount
}

animal.sleep = function (length) {
    console.log(`${this.name} is sleeping.`)
    this.energe += length
}

animal.play = function (length) {
    console.log(`${this.name} is playing.`)
    this.energe -= length
}

但通常的应用场景下,你会需要生成多种动物。这则需要把以上的逻辑抽象成一个函数。可见以下代码,生成了 leo 和 snoop 两个动物。

function Animal(name, energy){
    let animal = {};
    animal.name = name;
    animal.energy = energy;

    animal.eat = function (amount) {
        console.log(`${this.name} is eating.`)
        this.energy += amount
    }

    animal.sleep = function (length) {
        console.log(`${this.name} is sleeping.`)
        this.energy += length
    }

    animal.play = function (length) {
        console.log(`${this.name} is playing.`)
        this.energy -= length
    }
    return animal;
}

const leo = Animal('Leo', 7);
const snoop = Animal('Snoop', 10)

但是按照上面代码,每次新创建一个animal,就需要把里面的eat、sleep、play方法都会被重新创建一遍。

因为eat、sleep、play方法都很相似,所以我们可以把他们放在一个animalMethods里面,这样只需要在内存里面创建一次。然后每次我们需要创建一个新动物,我们只是指向了animalMethods里面的方法,而不是重新创造这些方法。

const animalMethods = {
    eat(amount) {
        console.log(`${this.name} is eating.`)
        this.energy += amount
    },
    sleep(length) {
        console.log(`${this.name} is sleeping.`)
        this.energy += length
    },
    play(length) {
        console.log(`${this.name} is playing.`)
        this.energy -= length
    }
}
function Animal(name, energy){
    let animal = {};
    animal.name = name;
    animal.energy = energy;
    animal.eat = animalMethods.eat;
    animal.sleep = animalMethods.sleep;
    animal.play = animalMethods.play;
    
    return animal;
}

以上代码中,比如animal增加一个方法poop,就需要到Animal函数 里面增加 animal.poop = animalMethods.poop 。 如果想要Animal总能指向 animalMethods里面的任何一个方法,可以使用Object.create()传入animalMethods,使得在Animal里面找不到对应属性或方法时,就会去animalMethods查找,并调用对应方法。

const animalMethods = {
    eat(amount) {
        console.log(`${this.name} is eating.`)
        this.energy += amount
    },
    sleep(length) {
        console.log(`${this.name} is sleeping.`)
        this.energy += length
    },
    play(length) {
        console.log(`${this.name} is playing.`)
        this.energy -= length
    }
}
function Animal(name, energy) {
    let animal = Object.create(animalMethods)
    animal.name = name;
    animal.energy = energy;

    return animal;
}
const leo = Animal('Leo', 7);
console.log(leo.play(7)) //Leo is playing.

以上的用法就是JavaScript 原型(prototype)的由来。

那么什么原型?它就是函数上的一个属性,指向一个对象。

既然原型是每个函数都有的属性,那么与其单独管理 animalMethods ,为什么我们不把 animalMethods 放到函数的原型上呢?

function Animal(name, energy) {
    let animal = Object.create(Animal.prototype)
    animal.name = name;
    animal.energy = energy;

    return animal;
}

Animal.prototype.eat = function (amount) {
    console.log(`${this.name} is eating.`)
    this.energy += amount
}
Animal.prototype.sleep = function (length) {
    console.log(`${this.name} is sleeping.`)
    this.energy += length
}
Animal.prototype.play = function (length) {
    console.log(`${this.name} is playing.`)
    this.energy -= length
}

const leo = Animal('Leo', 7);
console.log(leo.eat(5)) //Leo is eating.

以上代码告诉了我们三点:

如何创建一个构造函数(构造函数就是构造一个对象)
如何将方法添加到构造函数的原型上(eg:Animal.prototype.eat()={…})
如何使用Object.create()指向函数原型。
这三点的目的就是为了构造函数的所有实例都能共享实例上的方法。

接下来会引入关键词 new 来对上面代码再进行进一步优化。使用new关键词,js会自动做Object.create()和return的动作,并且需要使用this对象来替换原本的animal对象。

function Animal(name, energy) {
    // let this = Object.create(Animal.prototype) //这一步的作用:1、创建对象 2、指向Animal.prototype
    this.name = name;
    this.energy = energy;

    // return this; //输出创建的对象
}

Animal.prototype.eat = function (amount) {
    console.log(`${this.name} is eating.`)
    this.energy += amount
}
Animal.prototype.sleep = function (length) {
    console.log(`${this.name} is sleeping.`)
    this.energy += length
}
Animal.prototype.play = function (length) {
    console.log(`${this.name} is playing.`)
    this.energy -= length
}

const leo = new Animal('Leo', 7);
const snoop = new Animal('Snoop', 10)
console.log(leo.sleep(15)) //Leo is sleeping.

以上这些操作,就是基本上创建了一个class。在es6,JavaScript有了class关键词。接下来就用class来重构以上的代码。

class Animal {
    constructor(name, energy) {
        this.name = name
        this.energy = energy
    }
    eat(amount) {
        console.log(`${this.name} is eating.`)
        this.energy += amount
    }
    sleep(length) {
        console.log(`${this.name} is sleeping.`)
        this.energy += length
    }
    play(length) {
        console.log(`${this.name} is playing.`)
        this.energy -= length
    }
}

const leo = new Animal('Leo', 7);
const snoop = new Animal('Snoop', 10)
console.log(leo) //Animal { name: 'Leo', energy: 7 }
console.log(leo.sleep(1)) //Leo is sleeping.

既然可以用js建造class,那么为什么还需要花这么多时间了解上面的prototype,this,new?原因是class是function的语法糖,提供了更便捷的方式创建对象。class最终会被编译为function,其中的方法会成为prototype上面的共享方法。文章来源地址https://www.toymoban.com/news/detail-693365.html

到了这里,关于【个人笔记js的原型理解】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • js继承的几种方式(原型链继承、构造函数继承、组合式继承、寄生组合式继承、ES6的Class类继承)

    实现原理: 子类的原型指向父类实例 。子类在自身实例上找不到属性和方法时去它父类实例(父类实例和实例的原型对象)上查找,从而实现对父类属性和方法的继承 缺点: 子类创建时不能传参(即没有实现super()的功能); 父类实例的修改会影响子类所有实例 实现原理:

    2024年02月07日
    浏览(48)
  • JS 怎么理解ES6新增Set、Map两种数据结构?

    目录 一、前言 二、Set 1.Set数据结构定义 2.Set数据结构的特性 3.Set数据结构的基本使用 4.Set遍历数据 5.Set 的使用场景 6.WeakSet的使用 7.垃圾回收机制 三、Map 1.Map数据结构定义 2.Map数据结构的特性 3.Map数据结构的基本使用  4.Map遍历数据 5.Map的使用场景 6.WeakMap的使用 7.垃圾回收

    2024年02月08日
    浏览(37)
  • JavaScript笔记——快速了解 ES6 新增数组方法,开箱即用(含案例)

    数组是 JavaScript 以及多数编程其他编程语言的一种基础数据类型。 ES6 提供了许多新的数组方法,这篇文章将介绍其中一些常用的数组方法及其使用示例。 Array.from() 方法从一个类似数组或可迭代对象中创建一个新的,浅拷贝的数组实例。例如,将字符串转换为字符数组。 A

    2024年02月10日
    浏览(45)
  • JavaScript Es6_2笔记 (深入对象 + 内置构造函数 + 包装类型)+包含实例方法

    了解面向对象编程的基础概念及构造函数的作用,体会 JavaScript 一切皆对象的语言特征,掌握常见的对象属性和方法的使用。 了解面向对象编程中的一般概念 能够基于构造函数创建对象 理解 JavaScript 中一切皆对象的语言特征 理解引用对象类型值存储的的

    2024年02月12日
    浏览(47)
  • 数组的原型方法-es6

    数组的原型方法-es6 Array.form() Array.of() find() 和 findIndex() copyWithin() fill() entries(),keys()和values() includes() flat()和flatMap() 扩展运算符 at() reduce()和reduceRight() some()判断数组中是否存在满足条件的项 18、Array.form() Array.from方法用于将两类对象转为真正的数组:类似数组的对象(array-li

    2024年02月09日
    浏览(41)
  • 深入理解JavaScript原型与原型链

    JavaScript是一门基于原型的面向对象编程语言,它的原型和原型链是其核心特性之一。理解原型和原型链对于掌握JavaScript的面向对象编程非常重要。本文将深入探讨JavaScript原型与原型链,并通过代码举例进行说明。 在JavaScript中,每个对象都有一个原型对象。原型对象可以看

    2024年02月11日
    浏览(41)
  • 【JavaScript】数组方法 (ES6)

    arr.find(callback) 用于获取第 1 个符合要求的元素: callback : (item, index, arr) = boolean item -当前值、 index -当前索引、 arr -当前数组 返回值: callback 第一次返回 true 的对应 item ;如果没有符合的元素,则返回 undefined arr.findIndex(callback) 用于获取第 1 个符合要求的元素的下标: cal

    2024年02月14日
    浏览(59)
  • JavaScript ES6实现继承

    1 对象的方法补充 2 原型继承关系图 3 class方式定义类 4 extends实现继承 5 extends实现继承 6 多态概念的理 function 创建的名称如果开头是大写的,那这个创建的不是函数,是创建了类。 可以把class创建的类当做是function创建的类的一种语法糖。但是在直接使用的方面是有不同之处

    2024年02月16日
    浏览(48)
  • JavaScript 之 ES6 新特性

    在ES6中,模块化成为了JavaScript的标准特性。ES6模块化提供了一种更加优雅和可维护的方式来组织和管理JavaScript代码,可以有效地避免全局变量的污染和命名冲突的问题。以下是ES6模块化的一些主要特性: 导出(export): 可以通过 export 将一个变量、函数或类导出为一

    2024年02月07日
    浏览(49)
  • 【ES6】JavaScript中的Symbol

    Symbol是JavaScript中的一种特殊的、不可变的、不可枚举的数据类型。它通常用于表示一个唯一的标识符,可以作为对象的属性键,确保对象的属性键的唯一性和不可变性。 Symbol.for()是Symbol的一个方法,它用于创建一个已经注册的Symbol对象。当使用Symbol.for()创建Symbol对象时,会

    2024年02月10日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包