// new 的实现原理 // 简单的双向绑定 1.new 2.Function 3.this 若是函数挂载在一个对象上,做为对象的一个属性,就称它为对象的方法。当经过这个对象来调用函数时,该对象就是这次调用的上下文(context),也就是该函数的this的值。 4.constructor 用于初始化一个新建立的对象的函数就是这次调用的上下文。 在JS中函数即对象,程序能够随意操控它们。好比:JS能够把函数赋值给变量,或者做为参数传递给其余函数。由于函数就是对象,因此能够给它们设置属性,甚至调用它们的方法。 JS的函数可嵌套在其余函数中定义,这样它们就能够访问它们被定义时所处的做用域中的任何变量。这意味着JS函数构成了一个闭包(closure),它给JS带来了很是强劲的编程能力。编程
嵌套函数bash
function hypotenuse(a, b) {
function square(x) {
return x * x
}
return Math.sqrt(square(a) + square(b))
}
function square(x) {return x * x}
function hypotenuse(a, b) {
return Math.sqrt(square(a) + square(b))
}
复制代码
函数调用 构成函数主体的JS代码在执行之时并不会调用,只有调用该函数时,它们再回执行。有4种方式来调用JS函数。闭包
1.做为函数调用,对于普通的函数调用,函数的返回值成为调用表达式的值。若是该函数返回值是由于解释器到达结尾,返回值就是undefined。若是函数返回是由于解释器执行到一条return语句,返回值就是return以后的表达式的值,若是return语句没有值,则返回undefined。app
2.做为方法调用,方法和this关键字是面向对象编程范例的核心。任何函数只要做为方法调用实际上都会传入一个隐式的实参------这个实参是一个对象,方法调用的母体就是这个对象。函数
var o = {
m: function () {
var self = this
console.log(this === o)
f()
function f() {
console.log(this === o)
console.log(self === o)
}
}
}
o.m()
复制代码
3.做为构造函数ui
若是函数或者方法调用以前带有关键字new,它就构成构造函数调用。构造函数调用和普通的函数调用以及方法调用在实参处理、调用上下文和返回值方面都有不一样。 构造函数调用建立一个新的空对象,这个对象继承自构造函数的prototype属性。构造函数试图初始化这个新建立的对象,并将这个对象用作其调用上下文,所以构造函数能够使用this关键字来引用这个新建立的对象。this
4.经过它们的call()和apply()方法间接调用spa
JS中函数也是对象,函数也能够包含方法。 函数能够被任意次执行或调用。prototype
原型链 1.建立对象有几种方法 2.原型、构造函数、实例、原型链 3.instanceof的原理 4.new运算符双向绑定
1.建立对象有几种方法
方法1
var a = {name: 'mary'}
var b = new Object({name: 'john'})
a、b结果相同
方法2
var M = function(name) {this.name = name}
var c = new M('henri')
方法3
var P = {name: 'john'}
var d = Object.create(P)
d.__proto__ === p // true
复制代码
每个JS对象都和另外一个对象相关联,每个对象都从原型继承属性。
2.原型、构造函数、实例、原型链
实例:a,b,c都称为实例 构造函数:构造函数也是函数,任何函数只要被new操做的函数,就是构造函数。不使用new就是普通的函数。 函数:函数都有一个prototype属性,声明函数的时候就会被js引擎带上。对象没有prototype。实例有__proto__,函数没有。 原型对象:经过constructor(构造器)来区分被哪一个构造函数所引用。
M.prototype.constructor === M
c.__proto__ === M.prototype
M.__proto__ === Function.prototype
M.prototype.__proto__ === Object.prototype // true
Object.prototype是整个原型链的顶端
M.prototype.run = function () {
console.log('run fast')
}
var e = new M('mary')
此时c、e都有了run方法
复制代码
c instanceof M // true
c instanceof Object // true
c.__proto__ === M.prototype // true
M.prototype.__proto === Object.prototype // true
c.__proto__.constructor === M // true
c.__proto__.constructor === Object // false
所以用constructor比用instanceof更严谨
复制代码
4.1 一个新对象被建立。它继承自foo.prototype 4.2 构造函数foo被执行。执行的时候,相应的传参会被传入,同时上下文(this)会被指定为这个新实例。new foo等同于new foo(),只能用在不传递任何参数的状况下 4.3 若是构造函数返回了一个“对象”,那么这个对象会取代整个new出来的结果。若是构造函数没有返回对象,那么new出来的结果为步骤1建立的对象
new运算符背后的原理
var f = function(func) {
var o = Object.create(func.prototype)
var k = func.call(o)
if (typeof k === 'object') {
return k
} else {
return o
}
}
var h = f(M)
h instanceof M
h instanceof Object
h.__proto__.constructor === M
复制代码
函数其实是对象,每一个函数都是Function类型的实例,并且与其余引用类型同样具备属性和方法。因为函数就是对象,所以函数名实际上也是一个指向函数对象的指针,不会与某个函数绑定。M.proto === Function.prototype function M () {
} M.proto === Function.prototype
用constructor判断比instanceof要准确
__proto__
prototype
prototype
中继承属性和方法prototype
constructor
prototype
里面prototype
的属性和方法Object:既是对象,也是构造函数
Object.__proto__
=== Function.prototype
Object.prototype
是原型链的顶端,Object.prototype.__proto = null
Function: 既是对象,也是构造函数
Function.__proto__
=== Function.prototype
Function.prototype
用于共享,而Function.prototype.__proto__
继承自Object.prototype
Array(Date、Number...):既是对象,也是构造函数
Array.__proto__
=== Function.prototype
Array.prototype
用于共享,Array.prototype.__proto__
继承自Object.prototype
对象Person: 既是对象,也是构造函数
Person.__proto__
=== Function.prototype
Person.prototype
用于共享,·Person.prototype.__proto
继承自Object.prototype
所以: 一、原型链顶端是Object.prototype
二、构造函数建立的对象(Object、Fucntion、Array、普通对象等)都是Function的实例,它们的__proto__
均指向Function.prototype
三、除了Object,全部对象(或构造函数)的prototype
,均继承自Object.prototype