JS的prototype和__proto__(含es6的class)
JS的prototype和__proto__(含es6的class)
一、prototype和__proto__的概念
prototype是函数的一个属性(每个函数都有一个prototype属性),这个属性是一个指针,指向一个对象。它是显示修改对象的原型的属性。
__proto__是一个对象拥有的内置属性(请注意:prototype是函数的内置属性,__proto__是对象的内置属性),是JS内部使用寻找原型链的属性。
用chrome和FF都可以访问到对象的__proto__属性,IE不可以。
二、new 的过程
var Person = function(){};
var p = new Person();
new的过程拆分成以下三步:
(1) var p={}; 也就是说,初始化一个对象p
(2) p.__proto__ = Person.prototype;
(3) Person.call(p); 也就是说构造p,也可以称之为初始化p
关键在于第二步,我们来证明一下:
var Person = function(){};
var p = new Person();
alert(p.__proto__ === Person.prototype);
这段代码会返回true。说明我们步骤2是正确的。
三、示例
var Person = function(){};
Person.prototype.sayName = function() {
alert("My Name is Jacky");
};
Person.prototype.age = 27;
var p = new Person();
p.sayName();
p是一个引用指向Person的对象。我们在Person的原型上定义了一个sayName方法和age属性,当我们执行p.age时,会先在this的内部查找(也就是构造函数内部),如果没有找到然后再沿着原型链向上追溯。这里的向上追溯是怎么向上的呢?这里就要使用__proto__属性来链接到原型(也就是Person.prototype)进行查找。最终在原型上找到了age属性。
个人联系笔记(纯粹个人好理解的写法)
console.log('测试')
class css {
constructor(dd) { this.dd = '33333333333'; }
rr() { return 'rr' }
}
class aa extends css {
constructor() {
super() //extends的类里使用constructor必须要有super
this.b = this.b.bind(this);
this.dd = '2222222222222' }
b() { return 'ceshi' }
c() { return this.dd }//dd被修改 // return this b:function () dd:"2222222222222"
}
const bb = new aa()
// 上一个自身(constructor):__proto__ ; 自己:prototype 口诀:aa.__proto__.prototype
// aa的上一个自身的自己===上一个的自己
// ★★★★ 类里的__proto__找的是父级的constructor,类里的__proto__.prototype找的是父级的自己(父级.prototype)
// ★★★★ 实例对象的__proto__找的是父级的自己,即父级.prototype
console.log('-----------------------------------------') //
console.log('aa', aa) //
console.log('css', css) //
console.log('css.prototype', css.prototype) // 指向自身
console.log('css.prototype.__proto__', css.prototype.__proto__) // 指向自身
console.log('css.__proto__', css.__proto__) //function () { [native code] }
console.log('css.__proto__.__proto__', css.__proto__.__proto__) //
console.log('aa.__proto__', aa.__proto__) // 指向css的constructor aa.__proto__===css
console.log('aa.prototype', aa.prototype) // 指向自身
console.log('aa.__proto__.prototype', aa.__proto__.prototype) // 指向css的自身 aa.__proto__.prototype===css.prototype===aa.prototype.__proto__
console.log('aa.prototype.__proto__', aa.prototype.__proto__) // 同上
console.log('-----------------------------------------') //
console.log('bb', bb) // 指向aa的constructor, bb即aa的实例对象
console.log('bb.__proto__', bb.__proto__) // 指向父级自身即aa.prototype bb.__proto__===aa.prototype
console.log('bb.prototype', bb.prototype) // undefined
console.log('bb.__proto__.__proto__', bb.__proto__.__proto__) // 指向css自己 bb.__proto__.__proto__css.prototype
console.log('bb.__proto__.__proto__.__proto__', bb.__proto__.__proto__.__proto__) // bb.__proto__.prototype===aa.__proto__.prototype===css.prototype===aa.prototype.__proto__
console.log('bb.__proto__.__proto__.__proto__.__proto__', bb.__proto__.__proto__.__proto__.__proto__) // null
console.log('bb.__proto__.prototype', bb.__proto__.prototype) // undefined, 已经是自身了
// console.log('bb.prototype.__proto__',bb.prototype.__proto__) // err
console.log('-----------------------------------------') //
// const aaa = () => '1234567'
// console.log(aaa()) (()=>{a}) // 等价于 (function () { a; }); ()=>(a) // 等价于
// (function () { return a; });
console.log('********************************')
var Person = function(){ return 222;};
Person.prototype.sayName = function() { return 'cs'};
Person.prototype.age = 27;
var p = new Person();
p.__proto__.cs = 'cs'; //在Person.prototype里添加了cs='cs'
console.log('Person',Person) //Person function (){return 222}
console.log('Person.prototype',Person.prototype) //person自己
console.log('Person.prototype.__proto__',Person.prototype.__proto__) //Person.prototype.__proto__===Person.__proto__.__proto__===p.__proto__.__proto__
console.log('Person.__proto__',Person.__proto__) //function () { [native code] }
console.log('Person.__proto__.__proto__',Person.__proto__.__proto__)
console.log('p',p) // {}
console.log('p.prototype',p.prototype) //undefined
console.log('p.__proto__',p.__proto__) //p.__proto__===Person.prototype
console.log('p.__proto__.__proto__',p.__proto__.__proto__) //p.__proto__.__proto__ ==Person.__proto__.__proto__===Person.prototype.__proto__
console.log('********************************')
测试结果:
春雷原创:http://www.cnblogs.com/chunlei36
JS的prototype和__proto__(含es6的class)的更多相关文章
- JS的prototype和__proto__、constructor
看了JS的prototype和__proto__这篇文章,才感觉很清晰了,对于原型这块,以前经常把这些属性弄不清楚, 明白了之后保存下整理下: prototype: 是函数的一个属性(每个函数都有一个 ...
- Js中Prototype、__proto__、Constructor、Object、Function关系介绍
一. Prototype.__proto__与Object.Function关系介绍 Function.Object:都是Js自带的函数对象.prototype,每一个函数对象都有一个显式的proto ...
- JS的prototype和__proto__
一.prototype和__proto__的概念 prototype是函数的一个属性(每个函数都有一 个prototype属性),这个属性是一个指针,指向一个对象.它 是显示修改对象的原型的属性. _ ...
- 【转】Js中Prototype、__proto__、Constructor、Object、Function关系介绍
一 Prototype.__proto__与Object.Function关系介绍 Function.Object:Js自带的函数对象. prototype,每一个 ...
- JS的prototype和__proto__ Constructor
一.prototype和__proto__的概念 prototype是 注意是 只有函数的一个属性才有的(每个函数都有一个prototype属性),这个属性是一个指针,指向一个普通对象并且不是原型对象 ...
- js中prototype与__proto__区别
proto(隐式原型)与prototype(显式原型) 显式原型 explicit prototype property:每一个函数在创建之后都会拥有一个名为prototype的属性,这个属性指向函数 ...
- js中prototype,__proto__,constructor之间的关系
首先,我们需要了解三点: 1. 只要创建一个任意新函数,就会根据一个prototype属性,该属性指向函数的原型对象: 2. 每一个原型对象都会自动获得一个constructor属性,该属性只想pro ...
- js中prototype与__proto__的关系详解
一.构造函数: 构造函数:通过new关键字可以用来创建特定类型的对象的函数.比如像Object和Array,两者属于内置的原生的构造函数,在运行时会自动的出现在执行环境中,可以直接使用.如下: var ...
- js中的prototype和__proto__
var Person = function(name){ this.name = name; this.say = function(){ return "I am " + thi ...
随机推荐
- Django开发笔记二
Django开发笔记一 Django开发笔记二 Django开发笔记三 Django开发笔记四 Django开发笔记五 Django开发笔记六 1.xadmin添加主题.修改标题页脚和收起左侧菜单 # ...
- freeRTOS中文实用教程3--中断管理之中断嵌套
1.前言 最新的 FreeRTOS 移植中允许中断嵌套.中断嵌套需要在 FreeRTOSConfig.h 中设置configKERNEL_INTERRUPT_PRIORITY 和configMAX_S ...
- SQLServer语言之DDL,DML,DCL,TCL
数据库语言分类 SQLServer SQL主要分成四部分: (1)数据定义.(SQL DDL)用于定义SQL模式.基本表.视图和索引的创建和撤消操作. (2)数据操纵.(SQL DML)数据操纵分 ...
- CSS选择器中带点(.)怎么办?
在SharePoint中很多元素的ID都用点(.)来连接的,比如: <li class="ms-cui-group" id="Ribbon.Documents.Ed ...
- dns轮询
负载均衡最开始一步,利用它实现负载均衡集群的定位
- windows下搭建eclipse关于python的开发环境及初始化参数配置
1.安装jdk 因为eclipse是java开发的,运行eclipse程序需要安装jdk 安装jdk以后需要配置java_home环境变量 2.安装python2.7(比较简单,此处略) 3.下载ec ...
- S5PV210 PWM定时器
第一节 S5PV210的PWM定时器S5PV210共有5个32bit的PWM定时器,其中定时器0.1.2.3有PWM功能,定时器4没有输出引脚.PWM定时器使用PCLK_PSYS作为时钟源,相关知识可 ...
- 解决Android SDK下载和更新失败问题
今天更新sdk报错如下: Failed to fetch URL http://dl-ssl.google.com/android/repository/addons_list-1.xml. 说dl- ...
- 在listView中的模糊查询和删除
- java多线程快速入门(二)
通过继承Thread类来实行多线程 package com.cppdy; //通过继承Thread类来实行多线程 class MyThread extends Thread{ @Override pu ...