Javascript知识

严格模式(use strict)

"use strict" 指令只允许出现在脚本或函数的开头。

"use strict" 指令在 JavaScript 1.8.5 (ECMAScript5) 中新增。

它不是一条语句,但是是一个字面量表达式,在 JavaScript 旧版本中会被忽略。

"use strict" 的目的是指定代码在严格条件下执行。

严格模式下你不能使用未声明的变量。

为什么使用严格模式:

    消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;
  • 消除代码运行的一些不安全之处,保证代码运行的安全;
  • 提高编译器效率,增加运行速度;
  • 为未来新版本的Javascript做好铺垫。

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

另一方面,同样的代码,在"严格模式"中,可能会有不一样的运行结果;一些在"正常模式"下可以运行的语句,在"严格模式"下将不能运行。掌握这些内容,有助于更细致深入地理解Javascript,让你变成一个更好的程序员。

 

闭包

JavaScript 变量可以是局部变量或全局变量。

私有变量可以用到闭包。

闭包是一种保护私有变量的机制,在函数执行时形成私有的作用域,保护里面的私有变量不受外界干扰。

直观的说就是形成一个不销毁的栈环境

它使得函数拥有私有变量变成可能。

计数器受匿名函数的作用域保护,只能通过 add 方法修改。

例:

var add = (function () { var counter = 0; return function () {return counter += 1;} })();

立即执行函数

// 写法一 (function(){})() //写法二 (function(){}())

这两种是js中立即执行函数的写法,函数表达式后加上()可以被直接调用,但是把整个声明式函数用()包起来的话,则会被编译器认为是函数表达式,从而可以用()来直接调用。

立即执行函数一般也写成匿名函数,匿名函数写法为function(){/*...*/},就是使用function关键字声明一个函数,但未给函数命名,倘若需要传值,直接将参数写到括号内即可

立即执行函数的作用是:1.创建一个独立的作用域,这个作用域里面的变量,外面访问不到,这样就可以避免变量污染。2.闭包和私有数据。

惰性函数

var foo = function() {
    var t = new Date();
    foo = function() {
        return t;
    };
    return foo();
};

当foo函数第一次被调用的时候,我们会实例化一个新的Date对象,并且将foo变量重新赋值一个新的函数,这个函数能获取到闭包之中的Date对象。在第一次调用的结束之前新的foo函数会被调用,返回闭包中的变量。

之后所有对foo的调用都直接返回保存在闭包之中的变量t。这样当之前的判断逻辑非常复杂而且判断条件很多的情况下,这样的方案效率非常高。

另外一个对这个模式的思考角度是,一开始赋值给foo变量的外层函数是一个承诺。它会承诺第一次运行它后会将foo变量重写为一个更加有用的函数。术语“promise”来自scheme语言的惰性赋值机制。任何javascript程序员真的都应该去学习Scheme这种函数式编程语言。

hasOwnProperty()

JavaScript hasOwnProperty() 方法是 Object 的原型方法(也称实例方法),它定义在 Object.prototype 对象之上,所有 Object 的实例对象都会继承 hasOwnProperty() 方法。

hasOwnProperty() 方法用来检测一个属性是否是对象的自有属性,而不是从原型链继承的。如果该属性是自有属性,那么返回 true,否则返回 false。换句话说,hasOwnProperty() 方法不会检测对象的原型链,只会检测当前对象本身,只有当前对象本身存在该属性时才返回 true。

 

#define __wvjb_js_func__(x) #x 宏定义中#号的意思是将参数字符传化,例如

#define example1(instr) #instr
 
string str=example1(abc); 将会展成:string str="abc";

static NSString * preprocessorJSCode = @__wvjb_js_func__()等价于
static NSString * preprocessorJSCode = @""

requestAnimationFrame

setTimeout相比,requestAnimationFrame最大的优势是由浏览器来决定回调函数的执行时机,即紧跟浏览器的刷新步调。

优势:

CPU节能:使用setTimeout实现的动画,当页面被隐藏(隐藏的<iframe>)或最小化(后台标签页)时,setTimeout仍然在后台执行动画任务,由于此时页面处于不可见或不可用状态,刷新动画是没有意义的,而且还浪费 CPU 资源和电池寿命。而requestAnimationFrame则完全不同,当页面处于未激活的状态下,该页面的屏幕绘制任务也会被浏览器暂停,因此跟着浏览器步伐走的requestAnimationFrame也会停止渲染,当页面被激活时,动画就从上次停留的地方继续执行,有效节省了 CPU 开销,提升性能和电池寿命。

 

requestIdleCallback()

函数window.requestIdleCallback(),可以用来调节重新渲染。

它指定只有当一帧的末尾有空闲时间,才会执行回调函数。

 

requestIdleCallback(fn);

上面代码中,只有当前帧的运行时间小于16.66ms时,函数fn才会执行。否则,就推迟到下一帧,如果下一帧也没有空闲时间,就推迟到下下一帧,以此类推。

它还可以接受第二个参数,表示指定的毫秒数。如果在指定 的这段时间之内,每一帧都没有空闲时间,那么函数fn将会强制执行。


requestIdleCallback(fn, 5000);

上面的代码表示,函数fn最迟会在5000毫秒之后执行。

函数 fn 可以接受一个 deadline 对象作为参数。


requestIdleCallback(function someHeavyComputation(deadline) {
  while(deadline.timeRemaining() > 0) {
    doWorkIfNeeded();
  }

  if(thereIsMoreWorkToDo) {
    requestIdleCallback(someHeavyComputation);
  }
});

上面代码中,回调函数 someHeavyComputation 的参数是一个 deadline 对象。

deadline对象有一个方法和一个属性:timeRemaining() 和 didTimeout。

timeRemaining()

timeRemaining() 方法返回当前帧还剩余的毫秒。这个方法只能读,不能写,而且会动态更新。因此可以不断检查这个属性,如果还有剩余时间的话,就不断执行某些任务。一旦这个属性等于0,就把任务分配到下一轮requestIdleCallback

前面的示例代码之中,只要当前帧还有空闲时间,就不断调用doWorkIfNeeded方法。一旦没有空闲时间,但是任务还没有全执行,就分配到下一轮requestIdleCallback

 

 
posted @ 2021-01-14 17:56  小龙猫的萤火虫  阅读(71)  评论(0编辑  收藏  举报