总结自:https://www.cnblogs.com/wangfupeng1988/p/3977924.html
1. hasOwnProperty();
返回Boolean类型, 如果对象object有该属性, 返回true, 否则返回false
需要注意的是该方法不会检查对象的原型链中是否存在该属性, 该属性只有是对象本身的一个成员才会返回true;
2. 函数和对象的关系
函数就是对象的一种, 但函数和其他比如数组对象不一样, 它们间不仅仅是一种包含和被包含关系:
对象可以通过函数来创建, 或者说绝对一点, 对象都是通过函数来创建的.
3. 啥是对象呢?
一切引用类型都是对象, 对象就是若干属性的集合
4. prototype 和 _proto_
函数本身拥有prototype这个属性, 这个属性对应的值也是一个对象, 该对象中默认有constructor的属性, constructor指向这个函数本身.
new 函数 生成的对象, 即函数爸爸的儿子, 儿子都有一个_proto_的隐藏属性, 这个隐藏属性引用了爸爸的prototype.即 fn._proto_ === Fn.prototype.
每个函数function都有一个prototype,即原型。这里再加一句话——每个对象都有一个proto,可成为隐式原型。
image.png
5. 原型链
访问一个对象的属性时, 先在基本属性中查找, 如果没有, 再沿着_proto_这条链向上找,这就是原型链.
1、Object由Function创造。Function由自己创造Function的prototype又是对象。
2、三个指针:实例指针指向的是原型对象,构造函数指向函数对象,函数对象指向原型对象。
6. 上下文环境
上下文环境是在调用时创建的.
7. this指向谁?
- 构造函数中的this, 指向它new出的孩子.
- 函数作为对象的一个属性, 并作为属性被调用时, this指向该对象.
- call或apply时, this指向call或apply中传入的obj.
- this在原型链中, this代表的是当前对象的值.
- 全局环境下, this指向window.
- 总之一句话,谁调用的函数,this就指向谁.
值得注意的是这种情况:
函数f虽然是在obj.fn内部定义的, 但他仍是一个普通的函数, this依然指向window.
关于箭头函数中的this:
箭头函数本质是一个匿名内部函数,它没有this.所以this是继承下来的,并且这个继承是在定义函数的时候完成的。
这种情况下,this继承自module中的this, module是一个对象,它的this为window.
getX为module对象中的一个方法,方法中的this就是module对象本身。
同样的,箭头函数中的this来自function()方法,而function方法中的this为module.
obj.a调用后打出来的是obj对象,而obj.b.c调用后打出的是window对象而非obj,这表示多层对象嵌套里箭头函数里this是和最最外层保持一致的。
箭头函数中的this,到他的父函数中取寻找,本身没有this。
非箭头函数中的this, 看运行的时候,谁调用了,this指向谁。
参考:http://blog.csdn.net/yangbingbinga/article/details/61424363
词法作用域:当一个函数确定下来的时候,就会形成一个词法作用域,window本身为最大的那个词法作用域。箭头函数不会产生词法作用域。箭头函数中的this,就是看它所处的那个词法作用域中的this代表谁。注意,普通函数中的this不遵循这一规则。
8. 作用域
除了全局作用域, 只有函数才能创建作用域, 创建一个函数就创建了一个作用域, 无论你调不调用, 函数只要创建了, 他就有独立的作用域, 就有自己的一个地盘.
9. 作用域链
变量到底指向谁? 要到创建这个函数的那个作用域中取值, 是创建而不是调用, 如果没有找到, 那么就会到上一级的作用域中寻找改变变量, 这种一步一步向上跨的路线, 就是作用域链
10. 闭包怎么理解?
JavaScript中的函数运行在它们被定义的作用域里,而不是它们被执行的作用域里。
怎么理解这句话呢:
var foo = function(){
var name = "exe";
return function inner(){
console.log( name );
}
}
var bar = foo();//这里虽然得到的是函数inner的引用,而不是那一坨代码
bar();//这里开始执行inner函数,回头看看上面加粗的那句话
闭包有什么用? 为了能够读取其他函数内部变量函数.
本质上, 闭包就是将函数内部和函数外部连接起来的一座桥梁.
闭包最大的两个作用, 一个是可以读取函数内部的变量, 还有一个是让这些变量的值始终保持在内存中.
举个闭包的例子:
function f1(){
var n=999;
nAdd=function(){n+=1}//如果不用var命令,相当于申明为全局
function f2(){
alert(n);
}
return f2;
}
var result=f1();
result(); // 999
nAdd();
result(); // 1000
补充,可以查看闭包在for循环中的用法:https://www.cnblogs.com/copperhaze/p/6145302.html
11. 闭包和this结合
var obj = {
name: 'world',
sayHello: function() {
return function() {
console.log('hello', this.name);
}
}
}
obj.sayHello()();//hello
结果并没有打印world
将obj.sayHellow()();拆开来写就是这样
var a = obj.sayHello();//返回一个匿名函数。
var result = a();//执行该匿名函数,此时a()函数中的this并未和obj对象绑定,所以直接指向全局对象window.
为什么匿名函数没有取得其包含作用域(外部作用域)的this对象呢?
每个函数被调用时,其活动对象都会自动取得两个特殊变量:this和arguments。内部函数在搜索这两个变量时,只会搜索到其活动对象为止,因此永远不可能直接访问外部函数中的这两个变量。 《Javascript高级程序设计》
12. 闭包为什么能让其他函数访问内部变量?
以上这个例子, f2被赋给了一个全局变量, 所以f2一直被保存在内存中, 而f2的存在依赖f1, 所以f1也一直在内存中. 在f1()调用结束后, f1()的上下文环境不会出栈, 最终就能一直访问这个上下文环境中的内部变量.