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();//闭包 会延长 内部引用到的外部作用域的生命周期

 

 

posted @ 2017-11-19 21:09  兽人松  阅读(130)  评论(0编辑  收藏  举报