javascript语言学习笔记。
js类创建方法
var DogKing = function(dogName){ this.dogName = dogName; }; var myDogKing = new DogKing("奥巴马"); cc.log(myDogKing.dogName); //狗王奥巴马 //据说下面这种类的创建方式要比上面一种好。 var Dog = function(object){ var F = function(){}; F.prototype=object; return new F; }; var myDog = Dog({ dogName:"安倍晋三" }); cc.log(myDog.dogName); //狗王小弟安倍
js闭包
function f1(){ var n =99; nAdd = function(){n++;};//nAdd的值是一个匿名函数,而这个匿名函数本身也是一个闭包,所以nAdd相当于是一个setter,可以在函数外部对函数内部的局部变量进行操作。 function f2(){ //闭包函数,能在外部取函数内部的局部变量。因为在js中,只有函数内部的子函数才能读取局部变量,因此可把闭包简单理解成“定义在一个函数内部的函数” cc.log(n); } return f2; //所以本质上,闭包就是函数内部连向外部的一座桥梁。 } var test1 = f1(); test1(); //99 nAdd(); //nAdd前没有var,所以是个全局变量。 test1(); //100 函数f1的局部变量n一直保存在内存中,并没有在f1调用后被清除。因为f2被赋给了一个全局变量test1,导致f2始终在内存中,而f2依赖f1,所以f1也始终在内存中,不会在调用结束后,被垃回收。
在js中,对函数进行传参时,如果参数是数组,函数或是对象,并且在函数中对参数进行修改,那么会影响到函数体外的那个数组,函数或是对象。
代码如下:
var test = {abc:5}; function fuc(n){ n.abc = 2; n.xyz = 1; } fuc(test); cc.log(test.abc+","+test.xyz); //输出2,1 而不是5,1
但是仅限对参数的修改,如果是对参数赋值的话则没有引用效果,如下
var test = {abc:5}; function fuc(n){ n = {abc:4}; } fuc(test); cc.log(test.abc); //输出5
变量赋值技巧
var asd = xx||2; //如果xx是undefined或null或""空字符串,则asd的值为2,反之为xx。 var asd = xx?xx:2; //与上面等价
立即执行函数(匿名函数)
(function(c1,c2){ cc.log(c1+c2); //输出3 })(1,2); //因为匿名函数无法通过名称来调用,所以只能如此调用。
删除对象的属性
var as = {}; as.qqq = "as"; cc.log(as.qqq); //输出as delete as.qqq; cc.log(as.qqq); //不输出任何东西
JS会首先编译定义式函数,下面会先编译第二步代码,然后再读第一步的代码,所以俩个myfunc()都调用了第一步的函数。
var myfunc = function () //第一歩 { cc.log("yeah"); }; myfunc(); //输出yeah function myfunc() //第二步 { cc.log("hello"); }; myfunc(); //输出yeah
计算执行一段代码所需的时间(精确到毫秒),这里也表明了尽量少用with
//取值与赋值 10000 function noWith(){ var obj = a.a.a.a.a.a.a, i=100000, j = 0; for(; i; i--){ j = obj.b; obj.b = i; } } //取值与赋值 10000 function yesWith(){ var i=100000, j = 0; with( a.a.a.a.a.a.a ){ for(; i; i--){ j = b; b = i; } } } var t = new Date().getTime(); //console.time("Test") //noWith(); noWith(); cc.log(new Date().getTime() - t); //console.timeEnd("Test")
方法和函数的区别:
1.函数是过程式编程的叫法,而方法是OO编程的叫法。
2.函数显示调用参数,方法隐式调用参数(类对象调用方法,隐式参数是类对象)。
构造函数的一些知识:
object instanceof Class //判断object是否是Class的一个对象 Class.prototype.constructor==object.constructor //类和类对象的构造函数 object.hasOwnProperty("name") //如果name是object的本地属性(name也可以是父类属性),则返回true,如果name是prototype出来的属性或object没name属性,则返回false "name" in object //in用来判断name是否是object的一个属性,不管是否是本地属性还是prototype的属性。
js各元素关系:
var funcTest = function(){}; var objectTest = {}; var arrayTest = []; cc.log((funcTest.constructor===Function)+" "+typeof funcTest); //true function cc.log((objectTest.constructor===Object)+" "+typeof objectTest); //true object cc.log((arrayTest.constructor===Array)+" "+typeof arrayTest); //true object
js形参和实参的关系:
var object1 = {a:1}; var object2 = object1; function funTest(n){ cc.log(typeof n =="object"); } var object3 = {}; funTest(object3); //如果函数的参数是对象类型,那么实参object3和形参n的关系,就相当于object1和object2的关系。如果对这4个变量中的任一变量进行赋值,则不影响其相关的变量,如果进行修改,则影响其相关的变量
prototype属性和普通属性的区别:
function Person(name){ this.name=name; } Person.prototype.share=[]; Person.prototype.printName=function(){ alert(this.name); }; var person1=new Person('Byron'); var person2=new Person('Frank'); person1.share.push(1); person2.share.push(2); console.log(person2.share); //[1,2]
*待商榷的问题*
var myTest = function(){ }; myTest.prototype = { theOne:function(){cc.log(1)}, theTwo:"ff" }; /* 也可以下面这种方法写,但是如果上面这种方法除去了不必要的prototype属性,那么可能更好 myTest.prototype.theOne = function(){cc.log(1)}; myTest.prototype.theTwo = "ff"; */ var shili = new myTest(); shili.theOne(); //1 cc.log(shili.theTwo); //ff
代码中少用with,因为有出错率和效率上的问题。
var Sing = function () { with(arguments.callee) cc.log(Sing.author + " :" + this.poem); }; Sing.author = "李白"; Sing.poem = " 汉家秦地月,流影照明妃。一上玉关道,天涯去不归 "; Sing(); Sing.author = "李战"; Sing.poem = " 日出汉家天,月落阴山前。女儿琵琶怨,已唱三千年 "; Sing();