JavaScript严格模式

"use strict" 指令在 JavaScript 1.8.5 (ECMAScript5) 中新增。目的是指定代码在严格条件下执行。
严格模式通过在脚本或函数的头部添加 use strict; 表达式来声明。
ESM中的模块默认都是严格模式。

为什么使用严格模式:
消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;* 消除代码运行的一些不安全之处,保证代码运行的安全;

  • 提高编译器效率,增加运行速度;
  • 为未来新版本的Javascript做好铺垫。

"严格模式"体现了Javascript更合理、更安全、更严谨的发展方向,包括IE 10在内的主流浏览器,都已经支持它,许多大项目已经开始全面拥抱它。

严格模式的限制:
1、不允许使用未声明的变量: a = 3;
2、不允许删除变量:delete a

 **`delete` 操作符**用于删除对象的某个属性。如果对象包含该属性,那么该属性就会被移除。它不会触及原型链中的任何对象。删除对象的属性可能会让来自原型链中的属性透现出来。
 
 在严格模式下,如果对一个变量的直接引用、函数的参数或者函数名使用delete操作,将会抛出语法错误([`SyntaxError`]。因此,为避免严格模式下的语法错误,必须以`delete object.property`或`delete object['property']`的形式使用delete运算符。
 
 与通常的看法不同,`delete`操作符与直接释放内存**无关**。内存管理 通过断开引用来间接完成。

3、不允许变量重名:
4、由于一些安全原因,在作用域 eval() 创建的变量不能被调用:eval ("var x = 2"); alert (x);
5、.....完整内容点击标题链接......

JavaScript垃圾回收

引用
垃圾回收算法主要依赖于引用的概念。在内存管理的环境中,一个对象如果有访问另一个对象的权限(隐式或者显式),叫做一个对象引用另一个对象。例如,一个Javascript对象具有对它原型的引用(隐式引用)和对它属性的引用(显式引用)。

在这里,“对象”的概念不仅特指 JavaScript 对象,还包括函数作用域(或者全局词法作用域)。

引用计数垃圾收集算法
这是最初级的垃圾收集算法。此算法把“对象是否不再需要”简化定义为“对象有没有其他对象引用到它”。如果没有引用指向该对象(零引用),对象将被垃圾回收机制回收。

限制:循环引用

function f(){
  var o = {};
  var o2 = {};
  o.a = o2; // o 引用 o2
  o2.a = o; // o2 引用 o

  return "azerty";
}

f();

该算法有个限制:无法处理循环引用的事例。在下面的例子中,两个对象被创建,并互相引用,形成了一个循环。它们被调用之后会离开函数作用域,所以它们已经没有用了,可以被回收了。然而,引用计数算法考虑到它们互相都有至少一次引用,所以它们不会被回收。

标记-清除算法
这个算法把“对象是否不再需要”简化定义为“对象是否可以获得”。

这个算法假定设置一个叫做根(root)的对象(在Javascript里,根是全局对象)。垃圾回收器将定期从根开始,找所有从根开始引用的对象,然后找这些对象引用的对象……从根开始,垃圾回收器将找到所有可以获得的对象和收集所有不能获得的对象。

这个算法比前一个要好,因为“有零引用的对象”总是不可获得的,但是相反却不一定,参考“循环引用”。

从2012年起,所有现代浏览器都使用了标记-清除垃圾回收算法。所有对JavaScript垃圾回收算法的改进都是基于标记-清除算法的改进,并没有改进标记-清除算法本身和它对“对象是否不再需要”的简化定义。

Javascript中的基本数据类型:数字,字符串,逻辑类型,undefined,object, function
如果不考虑js的面向对象部分,JS是够简单的。

JavaScript面向对象
典型案例代码一:
1、编写图片有序、无需排序预加载插件:

(function($) {
  function Preload(imgs, options) { // ES5形式定义类
    // 相当于JAVA中类的成员属性和方法
    this.imgs = (typeof imgs === 'string') ? [imgs] : imgs;
    this.opts = $.extend({}, Preload.DEFAULTS, options)
    // 约定:下划线_开头的方法为内部使用,不提供外部调用
    if('ordered' === this.opts.order ) {
      this._ordered(); // 有序预加载
    } else {
      this._unordered(); // 无序预加载
    }    
  }
  
  // 相当于JAVA中类的静态成员属性和方法,类的实例对象共享,可以通过类名调用
  Preload.DEFAULTS = {
    order: 'unordered', // 插件默认设置
    each: null, // 每一张图片加载完毕后执行
    all: null // 所有图片加载完毕后执行
  }
  
  // 无序预加载方法
  Preload.prototype._unordered = function () {
    var imgs = this.imgs,
        opts = this.opts, 
        count = 0
    // 无序加载
    $.each(imgs, function(i, src) {
        var img = new Image()
        $(img).on('load error', function() {
          count++
          opts.each && opts.each() // 先判断传参是否空
          if(count >= imgs.length-1) {
            opts.all && opts.all() // 先判断传参是否空
          }
          ...
        })
        img.src = src
    })
  }
  
  // 有序预加载方法
  Preload.prototype._oderded = function () {
     var imgs = this.imgs,
         opts = this.opts,
         count = 0
     load()
     // 有序加载
     funciton load() {
        var img = new Image()
        $(img).on('load error', function() {
          count++
          opts.each && opts.each() // 先判断传参是否空
          if(count >= imgs.length-1) {
            opts.all && opts.all() // 先判断传参是否空
          } else {
            load()
          }
        })
        img.src = imgs[count]
     }   
        
  }
  
  // 写成jQuery插件
  $.extend({
    preload: function(imgs, opts) {
      new Preload(imgs, opts)
    }
  })
})(jQuery);

调用:$.preload(['https://xx.gif', ''], { 'ordered', function() {}, function() {} })

jQuery插件两种形式:
$.fn.extend -> $('#img').preload() // 挂载到jQuery.fn上,调用时可以选择元素后调用
$.extend -> $.preload() // 直接挂载到jQuery上,不需要选择元素


JohnsonGH
32 声望1 粉丝

« 上一篇
VUE2.x源码解析
下一篇 »
资源预加载