浅谈ECMAscript5-严格模式

        除了正常运行模式,ECMAscript 5添加了第二种运行模式:"严格模式"(strict mode)。
 
         Internet Explorer 10 之前的 Internet Explorer 版本不支持严格模式。
 

  设立”严格模式”的目的,主要有以下几个:

    1. 消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;

    2. 消除代码运行的一些不安全之处,保证代码运行的安全

   3. 提高编译器效率,增加运行速度;

   4. 为未来新版本的Javascript做好铺垫。

 

   严格模式需要使用到字符串序列:  "use strict"

   1.在全局代码的开始处.

   2.在eval代码开始处加入.

   3.在函数声明开始处加入

   4.在new function()所传入的body参数开始处加入

    

   注意:

   1.在正常模式中,如果一个变量没有声明就赋值,默认是全局变量。严格模式禁止这种用法,全局变量必须显式声明。

    严格模式下,变量都必须先用var命令声明,然后再使用。

           2.严格模式对动态绑定做了一些限制。某些情况下,只允许静态绑定。也就是说,属性和方法到底归属哪个对象,在编译阶段就确定。

    这样做有利于编译效率的提高,也使得代码更容易阅读,更少出现意外。

        (1)禁止使用with语句

        (2)创设eval作用域

            严格模式下,eval语句本身就是一个作用域,不再能够生成全局变量了,它所生成的变量只能用于eval内部。

           3.增强的安全措施

         (1)禁止this关键字指向全局对象   

  (2)禁止在函数内部遍历调用栈

          4.禁止删除变量、具名函数、arguments或形式参数名、catch子句中声明的异常对象

              严格模式下无法删除变量。只有configurable设置为true的对象属性,才能被删除。

           5.显式报错

 

         正常模式下,对一个对象的只读属性进行赋值,不会报错,只会默默地失败。严格模式下,将报错。

         严格模式下,对一个使用getter方法读取的属性进行赋值,会报错。

           6.重名错误       

 

 

 

 

          (1)对象不能有重名的属性

 

          (2)函数不能有重名的参数

        7.禁止八进制表示法

               正常模式下,整数的第一位如果是0,表示这是八进制数,比如0100等于十进制的64。严格模式禁止这种表示法,整数第一位为0,将报错。

            8.arguments对象的限制

            (1)不允许对arguments赋值

           (2)arguments不再追踪参数的变化

          (3)禁止使用arguments.callee

              这意味着无法在匿名函数内部调用自身了.

           9. 函数必须声明在顶层

             将来Javascript的新版本会引入"块级作用域"。为了与新版本接轨,严格模式只允许在全局作用域或函数作用域的顶层声明函数。

  也就是说,不允许在非函数的代码块内声明函数。

           10 .保留字

 

 

   为了向将来Javascript的新版本过渡,严格模式新增了一些保留字:implements, interface, let, package, private, protected,   public, static, yield.使用这些词作为变量名将会报错。

 “一切都是对象”这句话的重点在于如何去理解“对象”这个概念。

——当然,也不是所有的都是对象,值类型就不是对象。

 

函数也是一种对象,也是属性的集合,你也可以对函数进行自定义属性。每个函数都有一个属性叫做prototype。

这个prototype的属性值是一个对象(属性的集合),默认的只有一个叫做constructor的属性,指向这个函数本身。

 

 

每个函数function都有一个prototype,即原型。每个对象都有一个__proto__,可成为隐式原型。

每个对象都有一个__proto__属性,指向创建该对象的函数的prototype。 Object.prototype确实一个特例——它的__proto__指向的是null

Function.prototype指向的对象,它的__proto__也指向Object.prototype

 

 

 

instanceof

对于值类型,你可以通过typeof判断,string/number/boolean都很清楚,但是typeof在判断到引用类型的时候,返回值只有object/function,你不知道它到底是一个object对象,还是数组,还是new Number等等。

 

这个时候就需要用到instanceof

 

 

 

javascript中的继承是通过原型链来体现的。先看几句代码

 

 

以上代码中,f1是Foo函数new出来的对象,f1.a是f1对象的基本属性,f1.b是怎么来的呢?——从Foo.prototype得来,因为f1.__proto__指向的是Foo.prototype访问一个对象的属性时,先在基本属性中查找,如果没有,再沿着__proto__这条链向上找,这就是原型链

如何区分一个属性到底是基本的还是从原型中找到的 : hasOwnProperty

 

所有的对象的原型链都会找到Object.prototype,因此所有的对象都会有Object.prototype的方法。这就是所谓的“继承”。我们都知道每个函数都有call,apply方法,都有length,arguments,caller等属性。为什么每个函数都有?这肯定是“继承”的。函数由Function函数创建,因此继承的Function.prototype中的方法

 

原型的灵活性

 

 

 

 

 

 

执行上下文

 

 

在“准备工作”中完成了哪些工作:

  •       变量、函数表达式——变量声明,默认赋值为undefined;
  •       this——赋值;
  •       函数声明——赋值;  
 

    这三种数据的准备情况我们称之为“执行上下文”或者“执行上下文环境”。

 

    javascript在执行一个代码段之前,都会进行这些“准备工作”来生成执行上下文。这个“代码段”其实分三种情况——全局代码,函数体,eval代码

 

函数在定义的时候(不是调用的时候),就已经确定了函数体内部自由变量的作用

 

        

  

第一个例子中"a = 10"是对全局变量a重新赋值,第二个是重新声明一个a,作用域不同;
 
 
 
闭包 
应用的两种情况——函数作为返回值,函数作为参数传递。
 
闭包作用域与全局上下文环境分析:
 

    执行完第17行,fn()调用完成。按理说应该销毁掉fn()的执行上下文环境,但是这里不能这么做。注意,重点来了:因为执行fn()时,返回的是一个函数。函数的特别之处在于可以创建一个独立的作用域。而正巧合的是,返回的这个函数体中,还有一个自由变量max要引用fn作用域下的fn()上下文环境中的max。因此,这个max不能被销毁,销毁了之后bar函数中的max就找不到值了。

因此,这里的fn()上下文环境不能被销毁,还依然存在与执行上下文栈中。

    执行完20行就是上下文环境的销毁过程

 

    使用闭包会增加内容开销    

 
 
posted @ 2015-11-02 22:31  Lueny  阅读(41)  评论(0)    收藏  举报