草庐IT

[JS]原型的基本概念

feixianxing 2023-03-28 原文

原型系统

原型

基本概念

  • 原型(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()方法在原型对象上,是共享的。

有关[JS]原型的基本概念的更多相关文章

  1. Unity 热更新技术 | (三) Lua语言基本介绍及下载安装 - 2

    ?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------

  2. 计算机毕业设计ssm+vue基本微信小程序的小学生兴趣延时班预约小程序 - 2

    项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU

  3. ruby-on-rails - 使用 HTTParty 的非常基本的 Rails 4.1 API 调用 - 2

    Rails相对较新。我正在尝试调用一个API,它应该向我返回一个唯一的URL。我的应用程序中捆绑了HTTParty。我已经创建了一个UniqueNumberController,并且我已经阅读了几个HTTParty指南,直到我想要什么,但也许我只是有点迷路,真的不知道该怎么做。基本上,我需要做的就是调用API,获取它返回的URL,然后将该URL插入到用户的数据库中。谁能给我指出正确的方向或与我分享一些代码? 最佳答案 假设API为JSON格式并返回如下数据:{"url":"http://example.com/unique-url"

  4. ruby-on-rails - Rails 基本 Base64 身份验证 - 2

    我正在尝试复制此GETcurl请求:curl-D--XGET-H"Authorization:BasicdGVzdEB0YXByZXNlYXJjaC5jb206NGMzMTg2Mjg4YWUyM2ZkOTY2MWNiNWRmY2NlMTkzMGU="-H"Content-Type:application/json"http://staging.example.com/api/v1/campaigns在Ruby中,通过电子邮件+apikey生成身份验证:auth="Basic"+Base64::encode64("test@example.com:4c3186288ae23fd9661c

  5. ruby-on-rails - Assets 管道损坏 : Not compiling on the fly css and js files - 2

    我开始了一个新的Rails3.2.5项目,Assets管道不再工作了。CSS和Javascript文件不再编译。这是尝试生成Assets时日志的输出:StartedGET"/assets/application.css?body=1"for127.0.0.1at2012-06-1623:59:11-0700Servedasset/application.css-200OK(0ms)[2012-06-1623:59:11]ERRORNoMethodError:undefinedmethod`each'fornil:NilClass/Users/greg/.rbenv/versions/1

  6. ruby-on-rails - Rails - 理解 application.js 和 application.css - 2

    rails新手。只是想了解\assests目录中的这两个文件。例如,application.js文件有如下行://=requirejquery//=requirejquery_ujs//=require_tree.我理解require_tree。只是将所有JS文件添加到当前目录中。根据上下文,我可以看出requirejquery添加了jQuery库。但是它从哪里得到这些jQuery库呢?我没有在我的Assets文件夹中看到任何jquery.js文件——或者直接在我的整个应用程序中没有看到任何jquery.js文件?同样,我正在按照一些说明安装TwitterBootstrap(http:

  7. node.js - 如何在 Travis CI 上的一个项目中运行 Node.js 和 Ruby 测试 - 2

    我有一个包含多个组件的存储库,其中大部分是用JavaScript(Node.js)编写的,一个是用Ruby(RubyonRails)编写的。我想要一个.travis.yml文件来触发一个运行每个组件的所有测试的构建。根据thisTravisCIGoogleGroupthread,目前还没有官方支持。我的目录结构是这样的:.├──构建服务器├──核心├──扩展├──网络应用├──流浪文件├──package.json├──.travis.yml└──生成文件我希望能够运行特定版本的Ruby(2.2.2)和Node.js(0.12.2)。我已经有了一个make目标,所以maketest在每

  8. Simulink方法总结和避坑指南(一)——Simulink入门与基本调试方法 - 2

    文章目录一、项目场景二、基本模块原理与调试方法分析——信源部分:三、信号处理部分和显示部分:四、基本的通信链路搭建:四、特殊模块:interpretedMATLABfunction:五、总结和坑点提醒一、项目场景  最近一个任务是使用simulink搭建一个MIMO串扰消除的链路,并用实际收到的数据进行测试,在搭建的过程中也遇到了不少的问题(当然这比vivado里面的debug好不知道多少倍)。准备趁着这个机会,先以一个很基本的通信链路对simulink基础和相关的debug方法进行总结。  在本篇中,主要记录simulink的基本原理和基本的SISO通信传输链路(QPSK方式),计划在下篇记

  9. ruby - 是否有 Rack::Session::Cookie 用法的基本示例? - 2

    我找不到任何使用Rack::Session::Cookie的简单示例,并且希望能够将信息存储在cookie中,并在以后的请求中访问它并让它过期.这些是我能找到的唯一示例:HowdoIset/getsessionvarsinaRackapp?http://rack.rubyforge.org/doc/classes/Rack/Session/Cookie.html这是我得到的:useRack::Session::Cookie,:key=>'rack.session',:domain=>'foo.com',:path=>'/',:expire_after=>2592000,:secret=

  10. jquery - 在 Rails 中从原型(prototype)切换到 jquery,助手呢? - 2

    我目前从prototype切换到jquery主要是为了支持简单的ajax文件上传。我使用:https://github.com/indirect/jquery-rails95%的javascript代码是由railshelper编写的,例如:-remote_function-render:updatedo|page|-page.replace_html'id',:partial=>'content'-page['form']['name']=something-page.visual_effect:highlight,'head_success'...我知道我必须为Jquery重写5%

随机推荐