理解 JavaScript 原型 / 原型链
关于对象
以下代码中 p
的值是一个新对象,里面拥有 name
和 age
属性
function People(name, age){
this.name = name
this.age = age
}
var p = new People('evenyao', 27)
下面代码得到的结果同理,因为 return 的是一个 “非对象”
function People(name, age){
this.name = name
this.age = age
return 'hello'
}
var p = new People('evenyao', 27)
如果是下面代码, p
的值为一个新对象,里面拥有 a
和 b
属性
function People(name, age){
this.name = name
this.age = age
return {a: 1, b: 2}
}
var p = new People('evenyao', 27)
new
function Person(name) {
this.name = name
this.sayName = function() {
console.log('say name...')
}
}
var p = new Person('evenyao')
以上代码的执行过程如下:
- 执行 new Person
- 创建一个空对象 {},假设名字是 tmpObj
- 执行 Person 函数,执行过程中对 this 操作就是对 tmpObj 进行操作
- 函数执行完后返回刚刚创建的 tmpObj
- 把 tmpObj 赋值给 p (p也指向同一个对象)
instanceof
instanceof 是一个操作符,可以判断对象是否为某个类型的实例
构造函数
function Person(nick,age){
this.nick= nick
this.age = age
this.printName = function(){
console.log('say name...')
}
} var p1 = new Person('Byron',20)
var p2 = new Person('Casper',25)
//p1.printName()
//p2.printName()
图示可以看出,实例可以通过 __prop__
访问到其类型的 prototype
属性,这就意味着类的 prototype
对象可以作为一个公共容器,供所有实例访问。
抽象重复
//按照原型链的写法 使用公共容器
function Person(nick,age){
this.nick= nick
this.age = age
}
Person.prototype.sayName = function(){
console.log('say name...')
} var p1 = new Person('Byron',20)
var p2 = new Person('Casper',25)
// p1.sayName() `Byron`
// p2.sayName() `Casper`
这时候对应的关系是这样的
原型链
JS 在创建对象(不论是普通对象还是函数对象)的时候,都有一个叫做 __proto__
的内置属性,用于指向创建它的函数对象的原型对象 prototype
。在访问一个对象属性的时候,如果对象本身没有找到这个属性,就会沿着原型链一层一层的寻找。
总结原型
这三句话能解释一切关于原型方面的问题
当
new
一个函数的时候会创建一个对象,『函数.prototype
』 等于 『被创建对象.__proto__
』一切函数都是由
Function
这个函数创建的,所以『Function.prototype
===被创建的函数.__proto__
』一切函数的原型对象都是由
Object
这个函数创建的,所以『Object.prototype
===一切函数.prototype.__proto__
』
举例
案例1
扩展 String 的功能增加 reverse 方法,实现字符串倒序
var str = 'hello evenyao'
var str2 = str.reverse()
console.log(str2) // 'oayneve olleh'
即在String
的prototype
上添加 关于reverse
的function
,然后再调用 reverse()
String.prototype.reverse = function(){
return this.split("").reverse().join("")
console.log(this)
}
var str = 'hello evenyao'
var str2 = str.reverse()
console.log(str2) // 'oayneve olleh'
案例2
代码中并未添加
toString
方法,这个方法是哪里来的?
function People(){
}
var p = new People()
p.toString()
p.toString()
方法是继承构造函数 Object
的原型对象里定义的 toString
方法,首先 p
会找自己的 toString
方法;如果没有找到,就会沿着__proto__
属性继续到构造函数 People
的 prototype
里找 toString
方法;如果还是没有找到,再继续往 People.prototype
的 __proto__
即 Object.prototype
找 toString
方法,最后找到 toString
方法。
理解 JavaScript 原型 / 原型链的更多相关文章
- 三张图较为好理解JavaScript的原型对象与原型链
最近从网上看到别人详细得讲解了js的原型对象和原型链,看完感觉是看得最清晰的一个,于是,摘录到自己博客里 对于新人来说,JavaScript的原型是一个很让人头疼的事情,一来prototype容易与_ ...
- 理解 JavaScript 对象原型、原型链如何工作、如何向 prototype 属性添加新的方法。
JavaScript 常被描述为一种基于原型的语言 (prototype-based language)——每个对象拥有一个原型对象,对象以其原型为模板.从原型继承方法和属性.原型对象也可能拥有原型, ...
- 理解JavaScript的原型链
1. 什么是对象 在JavaScript中,对象是属性的无序集合,每个属性存放一个原始值.对象或函数. 1.1 创建对象 在JavaScript中创建对象的两种方法: ① 字面上: var myObj ...
- 理解JavaScript 的原型属性
1.原型继承 面向对象编程可以通过很多途径实现.其他的语言,比如 Java,使用基于类的模型实现: 类及对象实例区别对待.但在 JavaScript 中没有类的概念,取而代之的是一切皆对象.JavaS ...
- 深入理解javascript之原型
理解原型 原型是一个对象.其它对象能够通过它实现属性继承. 不论什么一个对象都能够成为继承,全部对象在默认的情况下都有一个原型.由于原型本身也是对象,所以每一个原型自身又有一个原型. 不论什么一个对象 ...
- 如何理解JavaScript的原型和原型链
在现在的业务开发中,应该很少人在写原生JavaScript了,大家都一股脑地扑在各个框架上.本来,这些框架对于业务和开发者来说是一种福音,减少了各种各样的开发痛点,但是带来的负面问题就是对于开发者来说 ...
- [我的理解]Javascript的原型与原型链
一.原型与原型链的定义 原型:为其他对象提供共享属性的对象 注:当构造器创建一个对象,为了解决对象的属性引用,该对象会隐式引用构造器的"prototype"属性.程序通过const ...
- 理解Javascript的原型和原型链
前言 本文2088字,阅读大约需要13分钟. 总括: 结合实例阐述了原型和原型链的概念并总结了几种创建对象的方法,扩展原型链的方法. 参考文章:The Secret Life of Objects,继 ...
- 简单理解javascript的原型prototype
原型和闭包是Js语言的难点,此文主要讲原型. 每一个方法都有一个属性是 prototype 每一个对象都有一个属性是 _proto_ 一旦定义了原型属性或原型方法,则所有通过该构造函数实例化出来的所有 ...
- 【深入理解javascript】原型
1.一切都是对象 一切(引用类型)都是对象,对象是属性的集合 typeof函数输出的一共有几种类型,在此列出: function show(x) { console.log(typeof(x)); / ...
随机推荐
- 全渠道价值链整合云服务 B2B SOLOMO(组图)
最近看到>中谈到“全渠道零售”(Omni-channel Retailing),指在互联网和电子商务的当今时代“零售商将能通过各种渠道与顾客互动,包括网站.实体店.服务终端.直邮和目录.呼叫中心 ...
- Oracle子查询之高级子查询
Oracle 高级子查询 高级子查询相对于简单子查询来说,返回的数据行不再是一列,而是多列数据. 1,多列子查询 主查询与子查询返回的多个列进行比较 查询与141号或174号员工的manager_id ...
- 浅析OC语言
学习一门开发语言,首先要掌握的它的基本语法,这可能几天就能学会,但如果要融会贯通,就得去学习这门语言的框架和一些库,再结合一些项目的应用,这可能需要花几年的时间. OC是C语言的一个超集,是一门面向对 ...
- 缓存反向代理-Varnish
简介 Varnish是一款高性能.开源的缓存反向代理服务器.它从客户端接受请求,并尝试从缓存中响应请求,如果无法从缓存中提供响应,Varnish 向后端服务器发起请求,获取响应,将响应存储在缓存中,然 ...
- SQL Server 2012 - SQL查询
执行计划显示SQL执行的开销 工具→ SQL Server Profiler : SQL Server 分析器,监视系统调用的SQL Server查询 Top查询 -- Top Percent 选择百 ...
- UEditor显示Invalid or unexpected token
原文链接http://www.qqdeveloper.com/a/53.html 问题背景 数据修改操作,需要做一个数据内容回显,该内容中包含代码.图片.普通文本等等内容,反正就是各种内容. 当 ...
- Redis(三):Redis数据类型
Redis数据类型目录导航: Redis五大数据类型 哪里去获取Redis常见数据类型操作命令 Redis键(Key) Redis字符串(String) Redis列表(List) Redis集合(S ...
- spring-构建mvc工程
SpringMVC基于模型-视图-控制器(MVC)模式实现,可以构建松耦合的web应用程序. 1.SpringMVC的请求过程 1)请求离开浏览器,并携带用户所请求的内容 2)DispatcherSe ...
- Qt——styleSheet
1.两个地方调用 QWidget::setStyleSheet() QApplication::setStyleSheet() 2.基本语法 selector {attribute : value} ...
- vim 配色方案
1. 自己电脑上的vim 注释很难看清,又不想取消高亮.原来显示: 在 if has("syntax") syntax onendif 语句下面追加一句: colorscheme ...