我不过略有一些讨人喜欢的地方而已,怎么会有什么迷人的魔力呢?
一.语法
JS只有一个数字类型,64位浮点数,所以1和1.0是相同的。为什么这么设计:防止短整型的溢出。
二.对象
1.通常将一个对象的值赋给另一个变量的赋值方法
if(car.name!=null){ a=car.name; }else{ a='unknown'; }
小技巧(给默认值):
a=car.name||"unknown";
2.尝试从一个对象的属性中取值
通常
if(car!=undefined){ a=car.age; }
小技巧:
a=car&&car.age;
3.枚举属性
通常我们会简单的使用for in
var name; for(name in car ){ ... }
这样的后果就是遍历出来的属性你可能无法预知,会遍历到原型上的属性
小技巧:不适用for in,取而代之用for循环
var properties=[ 'name', 'status', 'useTime' ]; for(var i=0;i<properties.length;i++){ car[properties[i]] ... }
4.删除属性
这个东西估计很少有人会使用到,但是存在既有道理,我就遇到过一个场景,在使用一个第三方的类库的时候,类库提供的方法创建的对象有我不需要的属性,而我要将这个对象转化为JSON格式的字符串,这个时候删除属性这个功能尤其的强大。
Delete car.name ;
三.函数
1.调用
JS中有4种调用方式
- 方法调用模式
- 函数调用模式
- 构造器调用模式
- apply调用模式
四种模式的差异在于 this指向
方法调用模式很好理解,我们写C#定义一个类CAR,给CAR定义一个方法RUN,这个时候实例化一个对象 jeep ,那么方法调用就是 jeep.RUN();
JS中同样如此
var jeep ={ run:function(){ ... } }; jeep.run();
this的指向为调用的对象。
函数调用模式,如下add2函数被调用的方式,直接写函数名
function add(a, b) { return a + b; } var shuxue={}; shuxue.calculate1 = function () { var add2 = function () { this.value=this.add(3, 3); } add2();//函数调用模式 } shuxue.calculate1();//方法调用模式 document.write(shuxue.value);//undefined shuxue.calculate2 = function () { var that=this; var add2 = function () { that.value=this.add(3, 3); } add2();//函数调用模式 } shuxue.calculate2();//方法调用模式 document.write(shuxue.value);//6
这里的this指向有点问题,JS设计之初把它指向了全局,如果这样就会导致上面代码的异常,代码定义了一个shuxue的对象,并给他定义了2个方法calculate1和calculate2,我们发现都同样在函数内部调用了add2函数,add2函数内试图给对象增加一个属性
value,calculate1的方式失败了,calculate2的方式成功了,区别在于后者把this(这时候的this是指向该函数的)给了函数的内部变量that,固定了下来,内嵌的函数使用外部函数的变量,也就是形成了闭包,前者this指向全局。
构造器调用模式
var Car=function(){}; var jeep=new Car(); //有个约定,如果函数是用来new的,那么大写开头,以区别于一般的函数
this指向这个new的对象
apply调用模式
JS是一门函数式的面向对象编程语言,所以函数可以拥有方法
function add(a, b) { return a + b; } var result=add.apply(null,[3,4]); document.write(result);// 7 function getName(){ return this.name; } var car={name:'jeep'}; var name=getName.apply(car);// car并没有getName方法 document.write(name); // jeep
this指向apply第一个参数
2.模块
我们知道JS很容易造成全局变量的滥用,所以JS提供了一个方法,利用闭包和和函数作用域(JS没有块级作用域ES6之前)构造模块
var man=function(){ var age=12; return { getYear:function(){ return age; }, setYear:function(n){ age=n; } } } var peter=man(); document.write(peter.getYear()); //12 peter.setYear(20); document.write(peter.getYear());//20 document.write(peter.age); //undefined 属性私有只能通过接口访问
3.级联
这个已经被广大程序猿们所喜爱了
var man=function(){ var age=12; return { getYear:function(){ alert(age); return this; }, setYear:function(n){ age=n; return this; } } } var peter=man(); peter.getYear().setYear(20).getYear(); //级联