• 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>
    我是一名小兵,总有一天我会成为将军
  • 相关阅读:
    最长回文字符(需要补)
    无重复字符的最长子串
    两数之和——链表
    两个数之和
    android 动画基础绘——帧动画(三)
    android 动画基础绘——view 动画(二)[补]
    android 动画基础绘——view 动画
    全国疫情精准定点动态更新(.net core)
    桶排序
    计数排序
  • 原文地址:https://www.cnblogs.com/wang0379/p/3940046.html
Copyright © 2020-2023  润新知