• Net学习日记_Js高级


    一.Js高级

    1.基本数据类型(值类型) 和 复杂数据类型(引用类型)

    怎么判断?

    凡是 instanceof Object 返回为true的,都是复杂数据类型。

    2. 对象 和 Json

     

    //2.Object 动态设置属性
    var o = new Object();
    o.id = 1;
    o["name"] = "james";
    
    //2.1对象字面量表示法
    var o1 = {
        id: 1,
        name:"哈哈"
    };

    Json 是数据在程序间传输的一种 数据格式(轻量级数据传输格式)

    //2.2Json格式字符串
    注意:字符串里的属性名和属性值必须有【双引号】扩起来
    var strJson = '{"id":"1","name":"哈哈"}';
    
    //2.2.1 使用eval将json字符串转成 obj,注意:加 ()
    var jsonObj = eval("(" + strJson + ")"); 
    alert(jsonObj.name);
    
    //2.2.2使用JSON.parse将字符串转成 obj
    注意:推荐使用此种方式,可以过滤掉不安全的js代码字符串
    var jsonObj = JSON.parse(strJson);
    alert(jsonObj.id + ":" + jsonObj.name);
    
    //2.2.3将对象 转成  json格式字符串
    var strJsonNew = JSON.stringify(jsonObj);
    alert(strJsonNew); 

     

    Json传输容量小,简便。

    3.数据类型

      3.1Function

    3.1.1声明式函数 特点:浏览器优先于其它执行js加载此声明式函数
    //A(1);//可以在声明式函数 之前 调用此函数!
    function A(a1) {
        alert("123"+a1);
    }
    //alert(A instanceof Function);//true
    
    3.1.2匿名方法
    var Ano = function (a,b) { alert(a);};
    //alert(Ano instanceof Function);//true
    
    3.1.3对象方式
    注意:最后一个参数永远是方法体代码字符串,前面的参数就是 改方法对象的 形参
    var funC = new Function("a","b","alert('123,'+a+','+b);");
    funC("hhaa ","吼吼");
    //alert(funC instanceof Function);//true
    
     
    3.2 Undefined 代表未定义,只有一个值:undefined
    3.2.1声明但未赋值,默认就是undefined
    var undef;
    alert(undef == undefined);//true
    
    3.2.2方法没有return,默认 返回 undefined
    function testUn() {
    
    }
    var tes = testUn();
    alert(tes == undefined);//true
    
    3.3Null 代表空引用
    var objN = new Object();
    objN = null;
    //null 和 undefined 都代表"没有",所以js把他们看成相等
    alert(null == undefined);
    //可以用 全等号 区别
    alert(null === undefined);
    
    3.4Boolean
    var boolV = true;
    alert(boolV == true);
    alert(boolV == 1);//js中 true==1 false==0
    
    3.5Number
    3.5.1包含 整数和浮点数
    var numb = 1;
    //alert(typeof numb);
    var numF = 1.11;
    //alert(typeof numF);
    
    3.5.2判断变量是否是 数值
    //isNaN 判断不是数值!:如果不是数值返回true,如果是数值返回false
    alert(isNaN("asdf"));
    
    3.5.3转换
    var intN = parseInt("111");
    var floatF = parseFloat("111.11");
    
    3.6string字符串
    
    length:得到长度
    split:根据指定分隔符拆分字符串
    substr:从下标为第一个参数的地方截取到第二个长度的内容
    substring:从下标为第一个参数的地方截取到下标为第二个参数的内容
    trim:去除字符串两头的空格
    indexOf:找到指定字符或字符串在这个字符串里第一次出现的位置
    lastIndexOf:找到指定字符或字符串在这个字符串里最后一次出现的位置
    charAt:找到指定下标位置的字符

    4.检测数据类型

    4.1 typeof:用来检测基本数据类型变量的数据类型,返回值 【变量类型字符串】

    语法: typeof num1 / typeof(num1)

    另外:是js里的关键字,不是一个方法!但也可以使用 typeof() 语法。

    4.1.2检测【基本数据类型】
    var s ="hahaha"; //var不是说变量没有类型,而是确定类型的时间推迟到运行这句代码时
    alert(typeof s); //string
    alert(typeof(s));//string
    alert(typeof 110);//number
    
    4.1.2如果用来判断【引用类型】对象,那么永远都返回Object
    alert(typeof null);//Object

    5.方法的内部属性 arguments

    //4.1arguments //方法的实参数组
    function testArgument() {
        //模拟函数重载!
        if (arguments.length == 1) {
            alert("哈哈~1"+arguments[0]);
        } else if (arguments.length == 2) {
            alert("哈哈~2" + arguments[0] + "," + arguments[1]);
        } else {
            alert("哈哈~3");
        }
    }
    testArgument();
    testArgument(1);
    testArgument(1, 2);

    注意:js中方法本身是没有重载的,因为:

    1.方法的本质就是一个Function类型的变量,如果出现同名的变量,会覆盖!

    但是依靠函数内部属性argument来模拟重载!

    补充:动态删除对象属性
    var oDel = new Object();
    oDel.id = 1;
    alert(oDel.id);//1
    //删除对象的 属性
    delete oDel.id;
    alert(oDel.id);//undefined

    6.js没有块级作用域

    function testBlock() {
        if (1 == 1) {
            var ablock = 1;
        }
        alert(ablock);//1
        for (var i = 0; i < 10; i++) {
        }
        alert(i);//10
        try{
            var tr="try";
        }catch(e){
                
        }
        alert(tr);//try
    }

    补充:关于自动垃圾回收

    1.主要针对 引用类型 对象(针对 堆空间),垃圾回收期会定时检查堆空间里的对象,一旦发现对象没有被任何地方引用的话,就把它删除销毁。

    2.引用类型:

       如果是局部变量,则方法执行完毕后变量被销毁,但对象要等待垃圾回收期来销毁。

       如果是全局变量,也是跟随全局对象存放,它的销毁依赖于 全局对象。

    3.值类型:

       如果是局部变量,则方法执行完毕后立即被销毁。

       如果是全局变量,直接跟随全局对象存放在堆中。它的销毁要看这个全局对象的销毁状态。

    补充:全局和局部变量

    全局变量:直接跟着全局对象存放在堆中;

    局部变量:在执行方法的时候,会在执行当前方法的线程栈和堆中 创建 值类型和引用类型变量。

    总结:只有值类型的 局部变量才会存在栈中,全局变量不管是什么类型都存在堆里。

    function test() {
        //局部变量
        var num = 1;//方法执行完 即销毁
        var objNum = new Object();//方法执行完,变量被销毁,但堆空间里的对象 要等垃圾回收器销毁
    }
    test();//注意:方法里的代码要被调用的时候才会执行,才会生成局部变量
    
    //而全局变量,则直接属于window,只有当窗体被关闭或刷新的时候 才跟随window一起销毁
    var temp = 1;
    var tempObj = new Object();

    7.数组

    7.1js数组不限制元素类型
    var arr = [1, 2, "asdf", new Object()];
    alert(arr.length);//4
    //7.2数组长度可变
    arr.length = 10;
    alert(arr.length);//10

    7.2数组当 栈和队列使用

    7.3数组当栈使用 栈(LIFO-LastInFirstOut-后进先出)方法
    //第一种:unshift(),shift()
    //第二种:push(),pop()
    var arrStack = [];
    arrStack.unshift("尾巴进来的第1个");
    arrStack.unshift("尾巴进来的第2个");
    arrStack.unshift("尾巴进来的第3个");
    arrStack.unshift("尾巴进来的第4个");
    alert(arrStack.length);
    for (var i = 0; i < 4; i++) {
        alert(arrStack.shift());
    }
    7.4数组当队列使用 队列(FIFO-FirstInFirstOut)方法
    //第一种:push(),shift()
    //第一种:unshift(), pop()
    
    var arrQue = [];
    arrQue.unshift("尾巴进来的第1个");
    arrQue.unshift("尾巴进来的第2个");
    arrQue.unshift("尾巴进来的第3个");
    arrQue.unshift("尾巴进来的第4个");
    alert(arrQue.length);
    for (var i = 0; i < 4; i++) {
        alert(arrQue.pop());
    }
    7.5反转数组
    var arrReverse = [4, 3, 1, 6, 8];
    alert(arrReverse);
    arrReverse.reverse();
    alert(arrReverse);
    7.5 排序
    var
    arrSortObj = [ { age: 18, name: "I笑傲呗" }, { age: 118, name: "乌龟" }, { age: 218, name: "王八" }, { age: 108, name: "蛤蟆" } ]; for (var i = 0; i < arrSortObj.length; i++) { document.body.innerHTML += arrSortObj[i].name + "," + arrSortObj[i].age + "<br/>"; } arrSortObj.sort(function (x, y) {//方法的参数,有sort方法内部传入(升序),方法的返回值约定:x > y 返回 正数,x=y 返回0,x<y 返回 负数 return x.age - y.age; }); document.body.innerHTML += "排序后:<br/><br/>"; for (var i = 0; i < arrSortObj.length; i++) { document.body.innerHTML += arrSortObj[i].name + "," + arrSortObj[i].age + "<br/>"; }

    8.arguments

    实参数组对象: 是一个 类(似)数组 对象

    内部属性arguments的callee

    8.1让我们来看一个函数递归的问题
    var facorial = function (num) {
        if (num <= 1)
            return 1;
        else
            return num * facorial(num - 1);//facorial是一个函数变量,其内部保存了函数的地址,但也可以在外部被修改指向其它的函数地址。从而破坏了递归应用。(很危险)
    }
    alert(facorial(5)); //5*4*3*2*1=120
    var another = facorial;
    alert(another(5));//5*4*3*2*1=120
    facorial = function () {
        return 1;
    }
    alert(another(5));//5*1=5
    alert(facorial(5));//1


    【解决方案】: var facorial = function (num) { if (num <= 1) return 1; else return num * arguments.callee(num - 1);//calle保存当前函数的引用,一般递归使用 } alert(facorial(5)); //5*4*3*2*1=120 var another = facorial; alert(another(5));//5*4*3*2*1=120 facorial = function () { return 1; } alert(another(5));//5*4*3*2*1=120 alert(facorial(5));//1

    9.函数内部属性this

    this引用的是函数据以执行操作的对象,也就是 函数在执行时所处的作用域

    通俗:就是哪个对象.出了这个函数,那么函数里的this就代表哪个对象

    window.color = "blue";
    var o = { color: "red" };
    function sayColor() {
        alert(this.color);//谁.出这个方法,这个this就是谁
    }
    sayColor();//blue
    o.sayColor = sayColor;
    o.sayColor();//red
    function each(arr,func)
            {
                if (arr instanceof Array)
                {
                    for (var i = 0; i < arr.length; i++)
                    {
                        var item = arr[i];
                        //通过 函数对象的 call/apply方法 改变函数的作用域(为被调用的函数 里的 this 赋值)
                        //func.call(item, i, item);
                        func.apply(item, [i, item]);
                    }
                }
            }
    
            var arr = [1, 2, 3, 4, 5];
    
            each(arr, function (index,item) {
                //alert(index + ":" + item);
                alert(this);
            });

    这样扩充的最大好处就是对象不需要与方法有任何耦合关系。

    10.方法的属性(区别方法内部属性)

    10.1length 代表方法的形参个数
    //9.1 length 函数的形参
    function testLength(name,id,cc) {
        //arguments.length
        //alert(arguments.callee.length);
    }
    //获取函数testLength形参的个数
    //testLength.length
            
    //将方法对象传入此方法,会根据 传入方法的形参个数决定传什么值!
    function invokeFun(func)
    {
        //当传进来的方法的形参是2个的时候
        if (func.length == 2) {
            func("哈哈","哇哈哈哈哈~~~");
        } else if (func.length == 3) {
            func(1, 2, 3);
        }
    }
    10.2方法属性:prototype,让那个所有方法实例共享数据的地方
    //9.2方法原型
    function Person(name, age) { //相当于 C#里的 类和 构造函数 的"综合体" ,Person : Object
        this.name = name;
        this.age = age;
        //this.sayHi = function () { alert("123123"); };
    }
    //Person.prototype是Person 实例共享数据的地方
    Person.prototype.sayHi = function () { alert("123123"); };
    
    /*
    new 关键字:
    0.开辟堆空间
    1.创建一个 Person 实例,内部没有任何成员,除了 "继承" 自 Object的成员;就相当于是一个Object实例!
    2.调用 同名构造函数,将 实例 设置给了 函数中的 this,从而 可以通过 这个函数 为每个new出来的Person实例 添加相同的属性!!!!!
    3.返回 实例 的地址
    */
    var p1 = new Person("james2", 28);
    var p2 = new Person("james3", 21);
    alert(p1.sayHi === p2.sayHi);//true
    10.3方法对象的call:动态修改方法里的this
    var sayColor= function (name,age){
        alert(this.color + ":" + name + ":" + age);
    }
    var oC = new Object();
    //将 方法引用 设置给了 oCol的sayColor属性
    oC.sayColor = sayColor;
    oC.color = "red";
    //oC.sayColor("james",18);//red
    
    var cNew = new Object();
    cNew.color = "yellow";
    oC.sayColor();
    //方法的call方法,用来动态修改 方法执行时的 this
    //执行 sayColor的同时,将sayColor方法里的this 修改成 colorNew
    oC.sayColor.call(colorNew, "james",18);//yellow
    
    var color = "green";
    //执行 sayColor的同时,将sayColor方法里的this 修改成 window
    oC.sayColor.call(window, "james", 18);
    方法对象的apply:动态修改方法里的this
    //9.4 apply 改变方法的this,但 实参必须作为一个数组传入
    var sayColor = function (name, age) {
        alert(this.color + ":" + name + ":" + age);
    }
    var oC = new Object();
    //将 方法引用 设置给了 oCol的sayColor属性
    oC.sayColor = sayColor;
    oC.color = "red";
    
    var cNew = new Object();
    cNew.color = "yellow";
    
    //方法的call方法,用来动态修改 方法执行时的 this
    //执行 sayColor的同时,将sayColor方法里的this 修改成 colorNew
    oC.sayColor.apply(cNew, ["james", 18]);//第二个参数必须是数组

    10.eval执行代码字符串

    function aa() {
        var strCode = "var aeval =1;";
        //eval方法里的代码就相当于在eval方法当前所在的作用域中执行
        eval(strCode);//相当于在此处 执行代码 var aeval =1;
    }
    window.onload = function () {
                document.getElementById("btnOk").onclick = function () {
                    var strCode = document.getElementById("txt").value;
                    //eval方法 可以直接调用 浏览器的js引擎,直接执行 传入的 js代码字符串
                    eval(strCode);
                };
            };
    
    
            //2.eval 中创建的变量 就是添加到 了 当前 eval所在的执行环境
            //2.1全局执行环境下 调用 eval 创建变量,那么这个变量就 添加到了 window下
            var str1 = "var i=0;";
            eval(str1);
            //alert(i);//? 0
    
            //2.2在方法中 调用 eval 创建变量,那么这个变量 就添加到了 函数的作用域中(局部变量)
            function testEval()
            {
                eval("var a =123;");
                alert(a);
            }
            testEval();
            
            var res = eval("1+2+3");
            alert(res);//? 6

     

    11.new创建对象

    <script type="text/javascript">
            
            //alert(Object instanceof Function);
            //var res = Object(123);
            //alert(res);
    
            function Person(age,name)
            {
                //this是 new关键字 创建的对象
                this.age = age;
                this.name = name;
                this.sayHi = function () {
                    alert("age=" + this.age + ",name=" + this.name);
                };
                //alert("Person的构造函数!" + this);//此时,this是 new关键字 创建的对象
            }
    
            var p1 = new Person(12, "刘德华");
            
            //p1.sayHi();
    
            var p2 = new Person(21, "习");
            //p2.sayHi();
    
            //通过 call 方法 模拟 new 关键字创建对象
            //var p3 = new Object();//1.创建一个对象
            //Person.call(p3, 99, "神州");//2.将对象 传给 Person 方法的 this,Person方法为 对象添加 属性
            //p3.sayHi();
    
            alert(p1 == p2);//false
        </script>
    <script type="text/javascript">
            function Person(age,name)
            {
                //this是 new关键字 创建的对象
                this.age = age;
                this.name = name;
            }
            //prototype(原型) 相当于是 某个 ”类“ 的 共享成员表(共享变量,共享方法)
            Person.prototype.sayHi = function () {
                alert("age=" + this.age + ",name=" + this.name);
            };
    
            var p1 = new Person(12,"刘德华");
            //p1.sayHi();
    
            var p2 = new Person(21, "习");
            //p2.sayHi();
    
            alert(p1.sayHi === p2.sayHi);//true 证明:每个Person对象 都使用一个 共同的 sayHi 方法对象
        </script>

    11.模拟继承

     <script type="text/javascript">
            function Mother()
            {
            }
    
            //1.定义"父类"
            function Father(name, age) {
                this.name = name;
                this.age = age;
            }
            Father.prototype.sayHi = function () { alert(this.name + "," + this.age); };
    
            //2.定义子类
            function Son(name, age,gender)
            {
                this.gender = gender;
                Father.call(this, name, age);//3."继承" "父类" 的成员
            }
    
            Son.prototype = new Father();//4.继承父类 的 方法
            Son.prototype.fungame = function () { };//5.为子类原型添加一个子类特有的方法
    
            //创建父类对象
            var f1 = new Father("JamesZou", 29);
            f1.sayHi();
            
            //创建子类对象
            var s1 = new Son("jameszou's son", 1, true);
            s1.fungame();
            
        </script>

    12.闭包

    闭包:指有权 访问另一个函数作用域中的变量的 函数
    function biBaoCreater() {
        var date = "2013-01-26";
        return function () {
            alert("今天:" + date);
        };
    }
    
    var biBao = biBaoCreater();//变量 biBao 就是一个 闭包
    biBao();//闭包 会延长 内部引用到的外部作用域的生命周期

  • 相关阅读:
    优先队列
    Problem W UVA 662 二十三 Fast Food
    UVA 607 二十二 Scheduling Lectures
    UVA 590 二十一 Always on the run
    UVA 442 二十 Matrix Chain Multiplication
    UVA 437 十九 The Tower of Babylon
    UVA 10254 十八 The Priest Mathematician
    UVA 10453 十七 Make Palindrome
    UVA 10163 十六 Storage Keepers
    UVA 1252 十五 Twenty Questions
  • 原文地址:https://www.cnblogs.com/lisong-home/p/7862037.html
Copyright © 2020-2023  润新知