function

// 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方法
复制代码
  1. instanceof 原理 instanceof判断对象的类型 判断实例对象的__proto__和构造函数的prototype是否为同一个引用(同一个地址),整条原型链上的都会返回true
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更严谨
复制代码
  1. new运算符

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里面
  • 经过new建立实例时,该实例变继承了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

相关文章
相关标签/搜索