目录
1.严格模式
1.1严格模式的概念:
严格模式有点像es5向es6过渡而产生的一种模式,因为es6的语法要求都比较严格,而我们在es5的代码编写过程中使用严格模式会使得我们的代码更加规范,但并不是所有的浏览器都支持严格模式,只有在IE10以上版本的浏览器才会支持严格模式。
1.2严格模式在语义上更改的地方:
严格模式对正常的 JavaScript 语义做了一些更改:
- 消除了 Javascript 语法的一些不合理、不严谨之处,减少了一些怪异行为。
- 消除代码运行的一些不安全之处,保证代码运行的安全。
- 提高编译器效率,增加运行速度。
- 禁用了在 ECMAScript 的未来版本中可能会定义的一些语法,为未来新版本的 Javascript 做好铺垫。比如一些保留字如:class,enum,export, extends, import, super 不能做变量名
1.3如何开启严格模式
"use strict" //开启严格模式,
//或者在函数内部
function(){
"use strict" //需要写在函数体内所有语句之前
}
如果将该语句直接写在script标签内部则表示开启全局严格模式。如果是写在函数内部,则表示在函数作用域内编写的代码开启严格模式。
1.4严格模式应用上的变化
(1)未声明的变量直接赋值输出会报错。(普通模式下不会报错,会将变量前面默认加上window然后将变量升为全局变量,可以在控制台输出变量的值)
"use strict" //开启严格模式,如果写在函数体内部则表示只有函数内部开启严格模式。
a = 10;
console.log(a);//严格模式之前可以输出a的值,现在会直接报错。
(2)不允许删除变量 (普通模式下变量没有真的被删除,但是也不会报错)
"use strict" //开启严格模式,如果写在函数体内部则表示只有函数内部开启严格模式。
var b = 1;
delete b;//严格模式下不可以删除变量,会直接报语法错误。
(3)函数的this指向是undefined(普通模式下,普通函数的this指向window)
<script>
"use strict" //开启严格模式,如果写在函数体内部则表示只有函数内部开启严格模式。
function fn() {
console.log(this); //严格模式下函数内this指向undefined
}
fn();
</script>
(4) 构造函数不加new调用,指向结果为undefined,(普通模式下,如果构造函数不使用 new
调用,this
的指向将取决于调用上下文。在非严格模式下,如果没有使用 new
,而是将构造函数作为普通函数进行调用,this
会指向全局对象(在浏览器环境中是 window
对象)。)
'use strict';
function Person(name) {
this.name = name;
}
var person1 = new Person('Alice');
console.log(person1.name); // 输出 "Alice"
var person2 = Person('Bob'); // 没有使用 new 关键字调用构造函数 此时由于没有使用 new 关键字,this 被设置为 undefined。在这种情况下,尝试给 undefined.name 赋值会导致报错,因为 undefined 没有 name 属性。
console.log(person2); // 输出 undefined
(5)无论是不是在严格模式下,定时器的this指向都是window。
setTimeout(function() {
console.log(this); //严格模式下,定时器 this 还是指向 window
}, 2000);
2.原型链
<script>
// 父亲 (构造函数)
function Person(name, age) {
this.name = name;
this.age = age;
this.say = function () {
console.log('say person');
}
}
// Person.prototype是原型对象 是一块空间 母亲 有 constructor属性和 __proto__属性
Person.prototype.say = function () {
console.log('asy');
}
Person.prototype.walk = function () {
console.log('walk');
}
// 孩子 实例对象 有 constructor属性和 __proto__属性
var p1 = new Person('TOM', 20);
var p2 = new Person('JACK', 22);
console.log(p1);
p1.say();
p2.say();
</script>
可以简单的理解为构造函数类似于父亲的角色,原型对象类似于母亲的角色,而实例对象类似于孩子的角色。
父亲(构造器)有prototype 属性,父亲(构造器)可以通过prototype 属性查找到母亲(原型对象)。
母亲(原型对象)有 constructor(构造器)属性和 __proto__(隐式原型)属性,母亲可以通过construtor属性来查找到父亲(构造函数)。同时可以通过 __proto__(隐式原型)属性来查找到父级函数的原型对象,而父级函数的原型对象再通过 __proto__(隐式原型)属性网上查找又可以找到上一级函数的原型对象,直到找到最顶部的原型对象,此时再向上查找的结果就是null。
孩子(实例对象)有 constructor(构造器)属性和 __proto__(隐式原型)属性,孩子可以通过 __proto__(隐式原型)属性查找到母亲(原型对象),然后再通过 construtor(构造器)属性查找到父亲(构造函数)或__proto__(隐式原型)属性查找到上级母亲(原型对象)。