首页 > 其他分享 >[JS]原型的基本概念

[JS]原型的基本概念

时间:2022-09-18 11:34:49浏览次数:74  
标签:name age JS Person 原型 prototype 基本概念 属性

目录

原型系统

原型

基本概念

  • 原型(prototype)是函数特有的属性。

  • 只要创建了一个函数,这个函数就会自动创建一个prototype属性(显式原型),并指向该函数的原型对象。

  • 原型对象上都有一个constructor属性,指向prototype属性所在的函数(即函数本身)。

  • 而对于每一个构造函数创建出的实例对象,内部都会有一个[[Prototype]]属性(隐式原型),同样指向函数的原型对象。

    • 在Firefox、Safari和Chrome浏览器中,每个对象都可以通过__proto__属性访问到它们的[[Prototype]]属性。

    • 对其他浏览器而言,这个属性对脚本是不可见的(使用getPrototypeOf()方法获取类的原型)。

示例

// 创建一个函数
function Person(){};

// 检查其是否有prototype这个属性
console.log(Person.hasOwnProperty('prototype'));
// 查看Person.prototype的内容
console.log(Person.prototype);

从输出结果可以看出,Person函数确实拥有prototype这个属性,并且Person.prototype这个原型对象包含了一个constructor属性,指向了一个函数,这个函数就是构造函数Person()

// 补充上面Person()构造函数的原型
Person.prototype.name = '张三';
Person.prototype.age = 20;
Person.prototype.sayName = function(){
    console.log(this.name);
}

// 创建对象
const person = new Person();
// 输出对象
console.log(person);

从输出结果可以看出,由于将属性和方法都放到了prototype上,输出person这个实例对象的时候是找不到nameagesayName()方法的,只有一个隐式原型对象[[Prototype]],在这个隐式原型对象上才能找到nameagesayName()方法,以及指向构造函数Person()constructor属性。

使用原型的好处就是可以共享属性和方法。

// 创建两个对象
const person1 = new Person();
const person2 = new Person();

console.log(person1 === person2);    // false
console.log(person1.sayName === person2.sayName);    // true
  • person1 === person2会返回false,因为它们是两个不同的对象。

  • person1.sayName === person2.sayName会返回true,因为这两个不同的对象共享这同一个sayName()方法。

关系

构造函数原型对象实例对象三个的关系如下图:

改进创建对象的模式

单纯使用原型模式创建对象

这种模式将所有的属性和方法都进行共享。

function Person(){};

// 将属性添加到原型上
Person.prototype.name = '张三';
Person.prototype.age = 20;
Person.prototype.sayName = function(){
    console.log(this.name);
}


const person1 = new Person();
const person2 = new Person();

确实,方法共享后,节省了内存,但是缺点是属性也随之共享了。

例如上面这个例子,person1person2这两个对象创建后的nameage都是张三20

可以再手动修改对象的属性:

person2.name = '李四';
person2.age = 18;

综合构造函数和原型模式创建对象

不需要共享的属性放在构造函数上,将共享的属性和方法放在原型对象上。

同时,可以使用默认值来改进构造函数。

function Person(name='张三', age=20){
    this.name = name;
    this.age = age; 
}

Person.prototype.sayName = function(){
    console.log(this.name);
}

const person1 = new Person();
const person2 = new Person('李四',18);

console.log(person1);
console.log(person2); 
  • Person()构造函数的参数列表:name='张三',age=20表示name的默认值是'张三'age的默认值是20

另一种设置默认值的方式是:

function Person(name,age){
    this.name = name || '张三';
    this.age = age || 20;
}

如果nameage没有传入参数,则为undefined,在运算符中会被转为false,最终赋值给nameage的是运算符右边的数据。

  • 由于person1在创建的时候没有传入参数,所以默认是张三,20;而person2在创建的时候传入了参数,所以属性是李四,18

  • 输出两个对象,发现它们只有nameage两个私有属性sayName()方法在原型对象上,是共享的。

标签:name,age,JS,Person,原型,prototype,基本概念,属性
From: https://www.cnblogs.com/feixianxing/p/javascript-prototype.html

相关文章

  • nodeJS中module.exports和exports的区别
      简单说就是,module.exprots是堆内存中的对象,而exports是栈内存中指向module.exprots的引用,实际上exports指向的是堆内存中的module.exprots的堆内存空间,所以需要用......
  • Angular vs AngularJS——2023 年更新
    AngularvsAngularJS——2023年更新Photoby奎因·巴蒂克on不飞溅Angular和AngularJS之间的主要区别是什么?Angular基于TypeScript而AngularJS基于Java......
  • js canvas2D CanvasImageRender.js 之 带图标的菜单
    1"usestrict";23var__emptyPoint=null,__emptyContext=null,__emptyPointA=null;45constColorRefTable={6"aliceblue":......
  • 实例-rust-将数据写入json文件
    Cargo.toml[package]name="rust-example5"version="0.1.0"edition="2021"#Seemorekeysandtheirdefinitionsathttps://doc.rust-lang.org/cargo/refere......
  • 实例-rust-将struct写入json文件
    cargo.toml[package]name="rust-example5"version="0.1.0"edition="2021"#Seemorekeysandtheirdefinitionsathttps://doc.rust-lang.org/cargo/refere......
  • 实例-rust-从json文件中读取数据并将输出写入json文件
    Cargo.toml[package]name="rust-example5"version="0.1.0"edition="2021"#Seemorekeysandtheirdefinitionsathttps://doc.rust-lang.org/cargo/refere......
  • js工厂模式和构造函数
    <!DOCTYPEhtml><html><head> <title>工厂模式和构造函数</title> <metacharset="utf-8"></head><body> <scripttype="text/javascript">//工厂模式跟构造函数//在js中......
  • JS实现保留几位小数
    根据不同的场景以及需求目前我用到的有两种一、保留2位小数(四舍五入)四舍五入的话很好解决:原生JS提供toFixed可以完美的实现四舍五入案例:letnumber=1.116number.toFi......
  • 在Go语言中,你是怎样使用Json的方法
    Encode将一个对象编码成JSON数据,接受一个interface{}对象,返回[]byte和error:func Marshal(v interface{}) ([]byte, error)Marshal函数将会递归遍历整个对象,依次按成......
  • json数据转成list后遍历报错
    错误代码:JSONObjectjsonObject=JSONUtil.parseObj(production);Map<String,Object>resultMap=newHashMap<>();resultMap.put("count",jsonObject.get("count"))......