揭开JavaScript的面纱



     一些容易混淆的语言特性
讲些什么呢

• 一 这(this),是什么?

• 二 这,是在哪(scope) ?

• 三 闭包和函数第一型有什么好处?

• 四 动态执行与元编程
一 这(this)是什么?

• 在传统的面向对象编程中,this指向对象的基址,而在js
  中呢?

•   四种函数调用方式:
•   1 过程式调用:指向宿主对象
•   2 访问调用:指向访问符前的对象
•   3 call,apply调用:自行传递this对象
•   4 new调用:指向隐式创建的 函数.prototype 的子对象
四种调用方式,四种this
•   function fun(){
•        return this===window ? 1 :
•                this===obj?2:
•                this===o2?3:
•                this instanceof arguments.callee?/4/:/5/;
•   }
•   var obj={fun:fun};
•   fun.prototype = obj;
•   var o2 = {};

•   console.log('过程式调用:', fun() );//1
•   console.log('访问修饰符式调用:', obj.fun() );//2
•   console.log('call调用:', fun.call(o2) );//3
•   console.log('new调用:', new fun() );// /4/
二 这是在哪(scope)


• 1 基于函数的词法作用域(静态作用域)
• Javascript的基本作用域规则是基于函数的词法作用域,
  即在不实际运行代码时,即可分析出一个变量的作用域。

• 2 由动态执行(eval,new Function)引起的动态作用域现象
词法作用域(静态作用域)

• function f1(){
•       var a=1;
•       function f2(){
•               if(false){
•                        var a=2;      //变量基于函数,而非基于
  语句块,没有块作用域
•               }
•               console.log(a); //undefined 未定义
•       }
•       f2();
•       console.log(a);//1
• }
• f1();
动态作用域

•   var a=1;
•   function f1(){
•         console.log(a);
•   }
•   function f2(){
•         var a=2;
•         eval(f1.toString());
•         f1();
•         console.log(f1 === window.f1);
•   }
•   f2();
三 闭包和函数第一型有什么好处?

• 1. 函数作为 语言本身所支持的基础类型

• 2. 延续变换 continues

• 3. 柯里变换 curry

• 4. 方法变换 methodize
函数作为语言本身所支持的基础类型

•   function add_1(a, b){
•       return a+b;
•   }
•   var add_2 = function(a, b){
•       return a+b;
•   }
•   var add_3 = new Function('a','b','return a+b');
延续变换 continues

• function continues(fn){
•       return function(){
•               var base_args =
  [].slice.call(arguments, 0, fn.length),
•               more_args = [].slice.call(arguments, fn.length),
•               ret = fn.apply(this, base_args),callee =
  arguments.callee;
•               if(more_args.length) return
  callee.apply(this, [].concat(ret,more_args));
•               return ret;
•       };
• }
柯里变换 curry
• function curry(fn, def_args){
•      return function(){
•               var real_args = [].slice.call(arguments),
•               use_args=[];
•
•               for(var i=0;i<def_args.length; i++){
•                        use_args.push(i in def_args ? def_args[i] :
  real_args.shift());
•               }
•               use_args = use_args.concat(real_args);
•
•               return fn.apply(this, use_args);
•      };
• }
方法变换 methodize

• function methodize(fn){
•     return function(){
•          return
  fn.apply(null, [this].concat([].slice.call(argume
  nts)));
•     };
• }
四 动态执行和元编程

• 1 动态执行之eval, new Function

• 2 元编程
• 元程序: 用来生成程序代码的程序
• 一门语言,同时也可以是自身的元语言的能力称为反射
生成程序代码并动态执行

• var opers = {add:'+',sub:'-',mul:'*',div:'/'};
• for(var key in opers){
•     eval(['var ',key,'=',(new
  Function('a','b','return
  a'+opers[key]+'b')).toString(),';'].join(''));
• }
thanks




         lichaosoft.net

揭开Javascript的面纱

  • 1.
    揭开JavaScript的面纱 一些容易混淆的语言特性
  • 2.
    讲些什么呢 • 一 这(this),是什么? •二 这,是在哪(scope) ? • 三 闭包和函数第一型有什么好处? • 四 动态执行与元编程
  • 3.
    一 这(this)是什么? • 在传统的面向对象编程中,this指向对象的基址,而在js 中呢? • 四种函数调用方式: • 1 过程式调用:指向宿主对象 • 2 访问调用:指向访问符前的对象 • 3 call,apply调用:自行传递this对象 • 4 new调用:指向隐式创建的 函数.prototype 的子对象
  • 4.
    四种调用方式,四种this • function fun(){ • return this===window ? 1 : • this===obj?2: • this===o2?3: • this instanceof arguments.callee?/4/:/5/; • } • var obj={fun:fun}; • fun.prototype = obj; • var o2 = {}; • console.log('过程式调用:', fun() );//1 • console.log('访问修饰符式调用:', obj.fun() );//2 • console.log('call调用:', fun.call(o2) );//3 • console.log('new调用:', new fun() );// /4/
  • 5.
    二 这是在哪(scope) • 1基于函数的词法作用域(静态作用域) • Javascript的基本作用域规则是基于函数的词法作用域, 即在不实际运行代码时,即可分析出一个变量的作用域。 • 2 由动态执行(eval,new Function)引起的动态作用域现象
  • 6.
    词法作用域(静态作用域) • function f1(){ • var a=1; • function f2(){ • if(false){ • var a=2; //变量基于函数,而非基于 语句块,没有块作用域 • } • console.log(a); //undefined 未定义 • } • f2(); • console.log(a);//1 • } • f1();
  • 7.
    动态作用域 • var a=1; • function f1(){ • console.log(a); • } • function f2(){ • var a=2; • eval(f1.toString()); • f1(); • console.log(f1 === window.f1); • } • f2();
  • 8.
    三 闭包和函数第一型有什么好处? • 1.函数作为 语言本身所支持的基础类型 • 2. 延续变换 continues • 3. 柯里变换 curry • 4. 方法变换 methodize
  • 9.
    函数作为语言本身所支持的基础类型 • function add_1(a, b){ • return a+b; • } • var add_2 = function(a, b){ • return a+b; • } • var add_3 = new Function('a','b','return a+b');
  • 10.
    延续变换 continues • functioncontinues(fn){ • return function(){ • var base_args = [].slice.call(arguments, 0, fn.length), • more_args = [].slice.call(arguments, fn.length), • ret = fn.apply(this, base_args),callee = arguments.callee; • if(more_args.length) return callee.apply(this, [].concat(ret,more_args)); • return ret; • }; • }
  • 11.
    柯里变换 curry • functioncurry(fn, def_args){ • return function(){ • var real_args = [].slice.call(arguments), • use_args=[]; • • for(var i=0;i<def_args.length; i++){ • use_args.push(i in def_args ? def_args[i] : real_args.shift()); • } • use_args = use_args.concat(real_args); • • return fn.apply(this, use_args); • }; • }
  • 12.
    方法变换 methodize • functionmethodize(fn){ • return function(){ • return fn.apply(null, [this].concat([].slice.call(argume nts))); • }; • }
  • 13.
    四 动态执行和元编程 • 1动态执行之eval, new Function • 2 元编程 • 元程序: 用来生成程序代码的程序 • 一门语言,同时也可以是自身的元语言的能力称为反射
  • 14.
    生成程序代码并动态执行 • var opers= {add:'+',sub:'-',mul:'*',div:'/'}; • for(var key in opers){ • eval(['var ',key,'=',(new Function('a','b','return a'+opers[key]+'b')).toString(),';'].join('')); • }
  • 15.
    thanks lichaosoft.net