15
揭揭 JavaScript 揭揭揭 揭揭揭揭揭揭揭揭揭揭

揭开Javascript的面纱

  • Upload
    qiang

  • View
    1.569

  • Download
    3

Embed Size (px)

DESCRIPTION

Beijing Perl Workshop 2011

Citation preview

Page 1: 揭开Javascript的面纱

揭开 JavaScript 的面纱

一些容易混淆的语言特性

Page 2: 揭开Javascript的面纱

讲些什么呢

• 一 这 (this) ,是什么?

• 二 这,是在哪 (scope) ?

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

• 四 动态执行与元编程

Page 3: 揭开Javascript的面纱

一 这 (this) 是什么 ?

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

• 四种函数调用方式:• 1 过程式调用:指向宿主对象• 2 访问调用:指向访问符前的对象• 3 call,apply 调用:自行传递 this 对象• 4 new 调用:指向隐式创建的 函数 .prototype 的子对

Page 4: 揭开Javascript的面纱

四种调用方式,四种 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/

Page 5: 揭开Javascript的面纱

二 这是在哪 (scope)

• 1 基于函数的词法作用域 ( 静态作用域 )• Javascript 的基本作用域规则是基于函数的词法作用域,

即在不实际运行代码时,即可分析出一个变量的作用域。

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

Page 6: 揭开Javascript的面纱

词法作用域 ( 静态作用域 )

• function f1(){• var a=1;• function f2(){• if(false){• var a=2; // 变量基于函数,而非基于语句块,

没有块作用域• }• console.log(a); //undefined 未定义• }• f2();• console.log(a);//1• }• f1();

Page 7: 揭开Javascript的面纱

动态作用域

• var a=1;• function f1(){• console.log(a);• }• function f2(){• var a=2;• eval(f1.toString());• f1();• console.log(f1 === window.f1); • }• f2();

Page 8: 揭开Javascript的面纱

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

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

• 2. 延续变换 continues

• 3. 柯里变换 curry

• 4. 方法变换 methodize

Page 9: 揭开Javascript的面纱

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

• 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');

Page 10: 揭开Javascript的面纱

延续变换 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;• };• }

Page 11: 揭开Javascript的面纱

柯里变换 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);• };• }

Page 12: 揭开Javascript的面纱

方法变换 methodize

• function methodize(fn){• return function(){• return fn.apply(null,

[this].concat([].slice.call(arguments)));• };• }

Page 13: 揭开Javascript的面纱

四 动态执行和元编程

• 1 动态执行之 eval, new Function

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

Page 14: 揭开Javascript的面纱

生成程序代码并动态执行

• 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(''));

• }

Page 15: 揭开Javascript的面纱

thanks

lichaosoft.net