原型与原型链
JavaScript
有着七种基本类型String
、Number
、Boolean
、Null
、Undefined
、Symbol
、Object
,前六种为基本数据类型,Object
为引用类型。函数本质上是Object
类型,也就是一个对象。
值得注意的是typeof (null)
会返回Object
,这是因为JS
二进制前三位都为0
的话会被判断为Object
类型,null
的二进制表示是全0
,自然前三位也是0
,所以执行typeof
时会返回Object
,实际null
为基本数据类型。
构造函数对象
构造一个Student
类,实例化Student
出stu
实例对象。
function Student ( ) { }
var stu = new Student ( ) ;
stu . name = "Ming" ;
console . log ( stu . name ) // Ming
prototype
每个函数对象都会有一个prototype
属性,prototype
就是调用构造函数所创建的那个实例对象的原型,prototype
可以让所有对象实例共享它所包含的属性和方法。
function Student ( ) { }
Student . prototype = {
from : "sdust"
}
var stu1 = new Student ( ) ;
var stu2 = new Student ( ) ;
console . log ( stu1 . from ) // sdust
console . log ( stu2 . from ) // sdust
__proto__
__proto__
是原型链查询中实际用到的,它总是指向prototype
,就是指向构造函数Student
的原型对象prototype
。例如实例化的stu
会使用__proto__
向Student
的prototype
寻找方法或属性。若stu
寻找到了调用的方法或属性,则不会使用__proto__
寻找原型对象。
function Student ( ) { }
Student . prototype = {
from : "sdust"
}
var stu = new Student ( ) ;
console . log ( stu . __proto__ === Student . prototype ) // true
console . log ( stu . from ) // sdust
stu . from = "s" ;
console . log ( stu . from ) // s
constructor
每个原型都有一个constructor
属性指向关联的构造函数Student
,实例的constructor
指向构造函数Student
。
function Student ( ) { }
var stu = new Student ( ) ;
console . log ( Student . prototype . constructor === Student ) // true
console . log ( stu . constructor === Student ) // true
原型链
原型链可以简单理解为将原型连成一条链,js
每一次获取对象中的属性都是一次查询过程,如果在自有属性中找不到就会去原型对象中查找,如果原型对象中还查不到,就回去原型对象的原型中查找,也就是按照原型链查找,直到查找到原型链的顶端,也就是Object
的原型。
function parent ( ) {
this . parentInfo = "parent" ;
}
parent . prototype . getParentInfo = function ( ) {
return this . parentInfo ;
} ;
function child ( ) {
this . childInfo = "child" ;
}
parent . prototype . getChildInfo = function ( ) {
return this . childInfo ;
} ;
child . prototype = new parent ( ) ;
var instance = new child ( ) ;
console . log ( instance . getChildInfo ( ) ) ; // child
console . log ( instance . getParentInfo ( ) ) ; // parent
console . log ( instance . parentInfo ) ; // parent
console . log ( instance . __proto__ === child . prototype ) ; //true
console . log ( instance . __proto__ . __proto__ === parent . prototype ) ; //true
console . log ( instance . __proto__ . __proto__ . __proto__ === Object . prototype ) ; //true
console . log ( instance . __proto__ . __proto__ . __proto__ . __proto__ === null ) ; //true
// function student(){}
// console.log(student.__proto__ === Function.prototype) // true
// console.log(Function.__proto__ === Function.prototype) // true
// console.log(Object.__proto__ === Function.prototype) // true
// console.log(Object.prototype.__proto__ === null) // true
每日一题
https://github.com/WindrunnerMax/EveryDay