diff --git "a/27 \350\265\265\346\265\251\346\225\217/\344\275\234\344\270\232/11.2 \344\270\245\346\240\274\346\250\241\345\274\217.html" "b/27 \350\265\265\346\265\251\346\225\217/\344\275\234\344\270\232/11.2 \344\270\245\346\240\274\346\250\241\345\274\217.html" new file mode 100644 index 0000000000000000000000000000000000000000..90e5acd3daee966070fb3fbc3cee04e89b7dd57d --- /dev/null +++ "b/27 \350\265\265\346\265\251\346\225\217/\344\275\234\344\270\232/11.2 \344\270\245\346\240\274\346\250\241\345\274\217.html" @@ -0,0 +1,76 @@ + + + + + + + Document + + + + + \ No newline at end of file diff --git "a/27 \350\265\265\346\265\251\346\225\217/\347\254\224\350\256\260/11.2\344\270\245\346\240\274\346\250\241\345\274\217.md" "b/27 \350\265\265\346\265\251\346\225\217/\347\254\224\350\256\260/11.2\344\270\245\346\240\274\346\250\241\345\274\217.md" new file mode 100644 index 0000000000000000000000000000000000000000..437b9e476accee86db38aace27b5bcee19040d07 --- /dev/null +++ "b/27 \350\265\265\346\265\251\346\225\217/\347\254\224\350\256\260/11.2\344\270\245\346\240\274\346\250\241\345\274\217.md" @@ -0,0 +1,236 @@ +# 11.2严格模式 + +## 1.1.1课上笔记 + +在严格模式下,函数内部不会意外生成全局变量 + +在严格模式下要求一个对象内的所有属性各在对象内必须唯一 + +null,undefined:没有包装类,严格模式会自动抛出错误,非严格模式会自动生成全局变量 + +构造函数使用严格模式必须使用new,普通函数小驼峰:getNameAge + +普通变量:personAge ,perons_age + +常量:PI + +函数自带方法 紫色盒子为方法 + +arguments:伪数组 只有下标 ,长度 + +改变this 指向 + +函数被执行时,内部会产生一个this + +```js + + function Person(name,age) { + this.name = name; + this.age = age; + } + var obj = {} + Person.call(obj,'张三',18) +``` + + + + + + + + + +## *严格模式的优缺点** + +优点: + +1. 提高代码解析与运行速度 +2. 禁用一些不合理的语法,减少代码的怪异行为 + +缺点 + +1. 某些代码在严格模式下会报错,尤其引入公用与第三方模块的时候需要注意 +2. 有些严格模式的特性在不同浏览器的支持情况不同,需要注意兼容问题 + +**严格模式与非严格模式的区别** + +**1.禁用with语法,使用将报错** + +因为解析with语法时作用域的情况会非常复杂,严重影响代码的解析与运行速度 + +```JS +function` `usualMode() { + ``with``({a: 1}) { + ``console.log(a) + ``} +} +usalMode() ``// 正常输出 1 +``` + + + +```JS +function` `strictMode() { + ``'use strict' + ``with``({a: 1}) { + ``console.log(a) + ``} +} +strictMode() ``// 将报错 +``` + +**2.禁止删除变量与函数** + +```JS +function` `usualMode() { + ``function` `fn() {} + ``var` `a = 1 + ``delete` `a ``// 不会报错,但实际上也没能删除变量a + ``delete` `fn ``// 同delete a +} +usalMode() ``// 正常执行 +``` + + + +```JS +function` `strictMode() { + ``'use strict' + ``function` `fn() {} + ``var` `a = 1 + ``delete` `a +} +strictMode() ``// 将报错 +``` + +## **3.属性描述符(propertyDescriptor)相关** + +能改变属性描述符的方法有Object.defineProperty、Object.defineProperties、Reflect.defineProperty、Reflect.defineProperties、Object.freeze、Object.seal;获取一个属性描述符可以用Object.getOwnPropertyDescriptor、Object.getOwnPropertyDecriptors,ES6中还有Reflect.getOwnPropertyDescriptor、Reflect.getOwnPropertyDescriptors + +### 3.1删除configurable = false的属性会报错 + +```js +'use strict' +var obj = {} +Object.defineProperty(obj, 'a', { + configurable: false, + value: 1 +}) +delete obj.a // 严格模式会报错;非严格模式会返回false +``` + +### 3.2给writable = false的属性赋值会报错 + +```js +'use strict' +var` `obj = {} +Object.defineProperty(obj, ``'a'``, { + ``writable: ``false``, + ``value: 1 +}) +obj.a = 2 ``// 严格模式会报错;非严格模式不会报错,但也不会生效,obj.a 仍然等于 1 +``` + +### **4.给不允许扩展的object增加属性会报错** + +```js +'use strict' +var` `obj = {a: 1} +Object.preventExtensions(obj) +obj.b = 2 ``// 严格模式下会报错;非严格模式不会报错,但也不会生效 'b' in obj 为false +``` + +能将object设置为不可扩展的方法有Object.freeze、Object.seal、Object.preventExtensions;ES6还有Reflect.freeze、Reflect.seal、Reflect.preventExtensions;判断一个object是否允许扩展可以用Object.isExtensible;ES6还有Reflect.isExtensible + +### **5.给未申明的变量赋值会报错** + +```js +'use strict'``a = 1 ``// 严格模式下将报错,非严格模式a变量会提升至全局作用域 +``` + +### **6.定义object时属性重名会报错** + +```js +'use strict'``var` `obj = {a: 1, a: 2}``// 严格模式将报错;非严格模式后面一个a会覆盖前面的a,即obj.a = 2 +``` + +### **7.形参重复时会报错** + +```js +'use strict'``function` `fn(a, a) {`` ``console.log(a, arguments)``}``fn(1,2) ``// 严格模式会报错;非严格模式不会报错,a=2,arguments中两个参数都有 +``` + +### **8.eval相关** + +#### 8.1eval有独立作用域 + +```js +'use strict'``eval(``'var a = 1'``)``console.log(``typeof` `a) ``// 严格模式下为undefined;非严格模式下为number +``` + +#### 8.2eval不能作为变量名或函数名,类似关键字 + +```js +'use strict'``var` `eval = 1 ``// 严格模式下将报错;非严格模式将申明一个值为1的变量eval` `// 严格模式下将报错;非严格模式将申明一个对应的eval函数``function` `eval() {``// some code``} +``` + +### **9.arguments相关** + +#### 9.1arguments是形参的副本(类似浅拷贝) + +```js +'use strict'``function` `fn(a, obj){`` ``arguments[0] = 2`` ``arguments[1].b = 2`` ``console.log(a) ``// 严格模式为1;非严格模式为2`` ``console.log(obj.b) ``// 2,因为js中object是地址传递``}``fn(1, {b: 1}) +``` + +#### 9.2arguments不能作为变量名或函数名,类似关键字 + +```js +'use strict'``var` `arguments = 1 ``// 严格模式下将报错;非严格模式将申明一个值为1的变量arguments` `// 严格模式下将报错;非严格模式将申明一个对应的arguments函数``function` `arguments() {`` ``// some code``} +``` + +### 10.禁用caller与callee + +```js +'use strict'``function` `fn() {`` ``console.log(arguments.callee.caller, fn.caller) ``// 严格模式下报错;非严格模式指向fn2`` ``console.log(arguments.callee) ``// 严格模式报错;非严格模式指向fn``}``function` `fn2() {`` ``fn()``}``fn2() +``` + + + + + +# 11.2 递归 + +**1 . 什么是递归:** +如果一个函数在内部可以调用其本身,那么这个函数就是[递归函数](https://so.csdn.net/so/search?q=递归函数&spm=1001.2101.3001.7020)。 +简单理解:函数内部自己调用自己, 这个函数就是递归函数 + +```js +//n! = n * (n-1)! + 1 function mul(n){ + 2 //找出口,即已知的条件或者结果 + 3 if(n == 1){ + 4 return 1; + 5 } + 6 //3. 写递归 + 7 //语句,调用自身 + 8 return = n * mul(n - 1); + 9 } +10 mul(8); +``` + +例子:斐波那契数列 + +```js + //斐波那契数列 + 2 //fb(n) = fb(n -1 ) + fb(n - 2) + 3 + 4 function fb(n){ + 5 if(n == 1 || n == 2){ + 6 return 1; + 7 } + 8 + 9 return fb(n-1) + fb(n-2); +10 } + +``` +