首页 > 代码库 > javascript高级编程

javascript高级编程

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>无标题文档</title><script type="text/javascript">    var array=[1,2,3,4,5,6];    var arr=array.map(function(item){            return item*2;        });    alert(arr[0]);// 2------------------------------------------------    /////变量的作用域    var variable="out";        function func()    {        variable="in";        alert(variable);     }    func();              // 打印"in"    alert(variable);   // 打印"in"------------------------------------------------    var object={            field:"self",            printInfo:function(){                alert(this.field);                }        }    alert(object.field);  //"self"    object.printInfo(); // "self"    for(var key in object){        alert(key+" : "+object[key]);    }------------------------------------------------///JavaScript对象    function Base(name) {        this.name = name;        this.getName = function () {            return this.name;        }    }    function Child(id) {        this.id = id;        this.getId = function () {            return this.id;        }    }    //将Child原型指向一个新的base对象    Child.prototype = new Base("base");    //实例化一个Child对象    var c1 = new Child("child");    //调用c1本身的getId方法    alert(c1.getId()); //child    //由于c1从原型链上“继承”到了getName方法,因此可以访问    alert(c1.getName()); //base    //////注解:由于遍历原型链时是由下而上的,所以最先遇到的属性值最先返回    function Person(name, age) {        this.name = name;        this.age = age;        this.getName = function () {            return this.name;        }        this.getAge = function () {            return this.age;        }    }    var tom = new Person("Tom", 30);    var jerry = new Person("jerry", 40);    ////注解:通过原型链,可以实现继承/重载等面向对象的js代码。当然这个机制并非基于类,而是基于原型------------------------------------------------    //定义个“类”,Address    function Address(street, xno) {        this.street = street || "黄泉路";        this.xno = xno || 135;        this.toString = function () {            return "street:" + this.street + ",No:" + this.xno;        }    }    //定义另外一个“类”,Person    function Person(name,age,addr){        this.name = name || "未知";        this.age = age;        this.addr = addr || new Address(null, null);        this.getName = function () {            return this.name;        };        this.getAge = function () {            return this.age;        };        this.getAddr = function () {            return this.addr.toString();        };    }    //通过new 操作符来创建两个对象,注意,这个两个对象是相互独立的实体    var jack = new Person("jack", 26, new Address("青海路", 123));    var abruzzi = new Person("abruzzi", 26);    //查看结果    alert(jack.getName()); //jack    alert(jack.getAge());  //26    alert(jack.getAddr()); //street:青海路,No:123    alert(abruzzi.getName()); //abruzzi    alert(abruzzi.getAge());   //26    alert(abruzzi.getAddr());  //street:黄泉路,No:135------------------------------------------------    ////函数作用域    var str = "global";    function scopeTest() {        alert(str);        var str = "local";        alert(str);    }    scopeTest();    //运行结果   undefined     local    ///注解:因为在函数scopeTest的定义中,预先访问了未声明的变量str,然后才对str变量进行初始化,所以第一个alert会返回undefined错误。    ///那为什么函数这个时候不会去访问外部的str变量呢?    ///这是因为在词法分析结束后,构造作用域的时候会将函数内定义的var变量放入该链,因此str在整个函数内部是可见的(从函数体的第一行到最后一行),    ///由于str变量本身是未定义的,程序顺序执行,到第一行就会返回为定义,第二行为str赋值------------------------------------------------    /////闭包    ///由于在javaScript中,函数是对象,对象是属性集合,而属性的值有可以是对象,则在函数内定义函数成为理所当然,如果在函数func内部声明函数inner,然后在函数外调用inner,这个过程即产生闭包。    var outter = [];    function clouseTest() {        var array = ["one", "two", "three", "four"];        for (var i = 0; i < array.length; i++) {            var x = {};            x.no = i;            x.text = array[i];            x.invoke = function () {                alert(i);            }            outter.push(x);        }    }    //调用    clouseTest();    outter[0].invoke();    outter[1].invoke();    outter[2].invoke();    outter[3].invoke();    ///运行结果是  4   4   4   4   为什么不是0   1   2   3呢?    //因为每次在迭代的时候,语句x.invoke=function(){alert(i);}并没有被执行,只是构建了一个函数体为“alert(i);”的函数对象而已。    //如果每次迭代的时候语句x.invoke=function(){alert(i);}执行的话,则调用clouseTest()的时候则就会弹出对话框了,事实上却没有弹,证明没有执行    //如何解决呢?    var outter = [];    function clouseTest2() {        var array = ["one", "two", "three", "four"];        for (var i = 0; i < array.length; i++) {            var x = {};            x.no = i;            x.text = array[i];            x.invoke = function (no) {                alert(no);            }(i);//调用            outter.push(x);        }    }    //调用    clouseTest2();------------------------------------------------    ///封装    var person = function () {        //变量的作用域为函数内部,外部无法访问        var name = "张飞";        return {            getName: function () { return name; },            setName: function (newName) { name = newName; }        }    }();    alert(person.name);//直接访问,结果为undefined    alert(person.getName());  //张飞    person.setName("关羽");    alert(person.getName());  //关羽    function Person() {        var name = "张飞";        return {            getName: function () { return name; },            setName: function (newName) { name = newName; }        }    };    var john = new Person();    alert(john.getName());  //张飞    john.setName("john");    alert(john.getName());  // john    ////在不同的Javascript解释器实现中,由于解释器本身的缺陷,使用闭包可能造成内存泄露(严重影响用户体验)    ///如:对象A引用B,B引用C,而C又引用A------------------------------------------------    ///【面向对象的JavaScript】    //原型继承:js中的继承可以通过原型链来实现,调用对象上的一个方法,由于方法在javascript对象中是对另一个函数对象的引用,因此解释器会在对象中查找该属性,    //如果没有找到,则在其内部对象prototype对象上搜索。由于prototype对象与对象本身的结构是一样的,因此这个过程会一直回溯到发现该属性,否则,报错    function Base() {        this.baseFunc = function () { alert("基础行为");}    }    function Middle() {        this.middleFunc = function () { alert("中间行为");}    }        Middle.prototype = new Base();    function Final() {        this.finalFunc = function () { alert("最终行为");}    }    Final.prototype = new Middle();    function Test() {        var obj = new Final();        obj.baseFunc();        obj.middleFunc();        obj.finalFunc();    }    Test();/////  基础行为   中间行为   最终行为     // 原型链示意图 见图  P76     ///new 操作符    function Shape(type) {        this.type = type || "rect";        this.calc = function () { return "calc," + this.type;}    }    var triangle = new Shape("triangle");    alert(triangle.calc());    var circle = new Shape("circle");    alert(circle.calc());    ////注解:Javascript和其他面向对象的new操作符不一样,triangle,circle可能在Java中是Shape对应的具体对象,但是在js中并非如此(new比较特殊)    ////首先,创建一个空对象,然后用函数apply方法,将这个空对象传入作为apply的第一个参数以及上下文参数,这样的函数内部的this将会被这个空的对象所替代。    var triangle = new Shape("triangle");    ///相当于下面的代码    var triangle = {};    Shape.apply(triangle, ["triangle"]);------------------------------------------------    ///柯里化    //柯里化就是余下将函数的某些参数传入,得到一个简单的函数,但是预先传入的参数被保存在闭包中,因此会有一些奇特的特性    var addr = function (num) {        return function (y) { return num + y;}    }    var inc = addr(1);    var dec = addr(-1);    alert(inc(99));  //100    alert(dec(101));  // 100    alert(addr(100)(2)); // 102    alert(addr(2)(100)); // 102------------------------------------------------    //开发智力(坑爹)    //函数的不动点    function fixedPoint(Func, first) {        var tolerance = 0.00001;        function closeEnough(x, y) {            return Math.abs(x - y) < tolerance;        };        function Try(guess) {            var next = Func(guess);            //alert(next+" "+ guess);            if (closeEnough(guess, next)) {                return next;//返回小的            }            else {                return Try(first);//递归调用            }        };        return Try(first);    }    //数层嵌套函数    function sqrt(x) {        var Func = function (y) {            var div = function (a, b) { return (a + b) / 2; }            return div(y, x / y);        }        return fixedPoint(Func, 1.0);    }    alert(sqrt(100));------------------------------------------------///原型链:由于原型对象本身也是对象,它也有自己的原型,而他自己的原型对象又可以有自己的原型,这样就组成了一条链,这个链就是原型链    ///Javascript引擎在访问对象的属性时,如果在对象本身中没有找到,则会去原型链中查找,如果找到,直接返回值,如果整个链都遍历且没有找到属性,则返回undefined。原型链一般是实现为一个链表,这样就可以按照一定的顺序来查找    var base = {        name: "base",        getInfo: function () {            return this.name;        }    }    var ext1 = {        id: 0,        __proto__:base    }    var ext2 = {        id: 9,        __proto__:base    }    alert(ext1.id);      //0    alert(ext1.getInfo()); //base    alert(ext2.id);    //9    alert(ext2.getInfo()); // base    //原型链图 见P105    var base = {     ///(原型对象)        name: "base",        getInfo: function () { return this.id + " : " + this.name;}    };    var ext1 = {   ///(原始对象)        id: 0,        __proto__:base    };    alert(ext1.getInfo()); // 0 : base    ///注解:getInfo函数中的this表示原始的对象,并非原型对象,上例中的id属性来自于ext1对象,而name来自base对象    ///如果没有显示的声明自己的”__proto__“属性,这个值默认的设置为Object.prototype,而Object.prototype的“__proto__”属性值为“null”,标志着原型链的终结------------------------------------------------    ///执行期上下文:按照ECMAScript的规范,一共有三种类型的代码,全局代码、函数代码、以及eval代码    ///this上下文:ECMAScript的规范中对this的定义为:this是一个特殊的对象,与执行期上下文相关,因此可以称为上下文对象。    ///this是执行期上下文对象的一个属性(执行期上下文对象包括变量对象、作用域链以及this)。执行期上下文对象有三类,当进入不同的上下文时,this的值会确定下来,并且this的值不能更改。    ///在执行全局代码时,控制流会进入全局执行期上下文,而在执行函数时,又会有函数执行期上下文    var global = this;    var tom = {        name: "Tom",        home: "desine",        getInfo: function () {            alert(this.name + ", from " + this.home);        }    };    tom.getInfo();   // Tom,from desine    var jerry = {        name: "Jerry",        getInfo:tom.getInfo    };    jerry.getInfo();   // Jerry,from undefined        global.getInfo = tom.getInfo;    global.getInfo();   // ,from undefined</script></head><body></body></html>

 

javascript高级编程