《Javascript for PHP Developers》读书笔记

这本书一共才130多页,当时在图书馆借这本书的时候,纯粹是因为它把部分php和javascript放在一起对比。后来看下去,知识点讲的不细,但是对Javascript整体容易犯错的地方都有解释。而且由于书特别薄,所以读起来也比较方便,目录很清晰。所以还是不错的。下面记录的是我看书的时候发现的一些知识点的漏洞或者是总结。先让我们看看这本书的真面目:


默认参数可能要注意的一个坑

1
2
3
4
5
function sum(a,b){
b = b||2;
return a+b;
}
console.log(sum(2,0));

我想要把2和0相加,最后得到2,但是这个的输出结果确实4,大家一看肯定明白为什么会输出4了吧。因为当我们传入0的时候,这种比较会得到结果为false。一个可行解决方案是使用typeof。平时要注意这个。

1
2
3
4
5
function sum(a,b){
b = typeof b === "undefined"?2:b;
return a+b;
}
console.log(sum(2,0));


substr是非标准的

顺便总结下截取字符串的三种方法。

1
2
3
console.log(s.slice(4,7));
console.log(s.substring(4,7));
console.log(s.substr(4,3));


几种编码URL方法和它们的区别和联系

encodeURIdecodeURI类似于encodeURIComponentdecodeURIComponent,区别在于前者只是编码需要编码的那一部分,将类似于Http://的这个部分是不用动的。并且要注意encodeURI不编码&,具体想用哪个可以根据具体的需求来。

1
2
3
4
5
6
7
8
9
var testUrl = "https://www.baidu.com/s?r ds v_bp=0&bar=&rsv_spt=3";
console.log(encodeURIComponent(testUrl));
console.log(decodeURIComponent(encodeURIComponent(testUrl)));

console.log(encodeURI(testUrl));
console.log(decodeURI(encodeURI(testUrl)));

console.log(escape(testUrl));
console.log(unescape(escape(testUrl)));

编码Url

这里提一下escape和unescape,他们不是ECMAScript的一部分,他们来自于BOM,我们尽量应该避免使用它们。


关于null和undefined

undefined返回的值总是字符串,所以下面这种情况要注意。

1
2
3
4
5
6
var a;
console.log(a);
console.log(a == undefined);
console.log(a == "undefined");
console.log(typeof a == undefined);
console.log(typeof a == "undefined");

答案是: undefined, true, false, false, true。null要注意的就是typeof null结果是object就行了。


删除属性

1
2
3
4
var obj = {one:1,two:2};
delete obj.one;
//obj.one = null;
console.log(obj);

以前删除一个属性,大部分都是用的obj.one = null这种形式,现在看来我真的是大错特错了。用delete删除,最后obj是Object {two: 2},one确实被去掉了,而且通过obj.one再去访问的时候,返回的是undefined。但是当我们通过赋值为null这种形式时,它只是被重新赋值为null了,而不是完全的删除了。


php和js的try-catch有什么区别?

区别记录如下:

1. js抛出的是Error对象,而不是Exception对象。
2. 捕获时,js没有声明类型。
3. 访问message属性,而不是调用getMessage方法。

具体来看看代码:

1
2
3
4
5
6
7
8
9
var msg = "";
try{
throw new Error("ouch");
}catch(e){
msg += e.message;
}finally{
msg += "-finally";
}
console.log(msg);

答案是ouch-finally;看看php是怎么写的:

1
2
3
4
5
try{
throw new Exception("ouch");
}catch(Exception $e){
$msg = $e.getMessage();
}


全局变量和全局对象的属性的细微区别

1
2
3
4
5
6
7
8
9
10
var john = "Jo";
console.log(john);
console.log(window.john);

window.jane = "Jane";
console.log(jane);
console.log(window.jane);

console.log(delete window.john);
console.log(delete window.jane);

结果是Jo,Jo,Jane,Jane,false,true。主要注意下这个false。
我们可以把全局变量当成是全局对象的属性来看,唯一的不同之处在于,你无法删除它们。看这里的john是无法被delete删除的。


利用parseInt把CSS十六进制颜色定义转换为rgb()

1
2
3
4
5
6
7
8
9
function getRGB(color){
var r = parseInt(color[1]+color[2],16);
var g = parseInt(color[3]+color[4],16);
var b = parseInt(color[5]+color[6],16);

return "rgb("+r+","+g+","+b+")";
}
var color = "#ff0000";
console.log(getRGB(color));

最后的结果是:rgb(255,0,0),总结下全局函数中四个与数字相关的函数分别是:isNaN(),isFinite(),parseInt(),parseFloat()


toString()方法

1
2
3
4
5
var o = {};
console.log(o.toString());
console.log(Object.prototype.toString.call(o));
//字符串"[object Object]"对于任何对象都是相同的,所以下面返回true
console.log(Object.prototype.toString.call({}) === Object.prototype.toString({a:1}));

toString()方法存在于Object.prototype之上,因此,可以像上面那样使用它们。toString方法一般用于测试数组,由于一些原因,其他的一些测试数组方法都会有缺陷,下面的是目前稍微好一点的解决办法。

1
2
3
4
5
6
7
function isArray(arr){
if(!Array.isArray){
return Object.prototype.toString.call(arr) === "[object Object]";
}
return Array.isArray(arr);
}
isArray([1,2]);

构造器函数

Number,String,Boolean,这些,如果直接使用构造器函数,而不是以new一个对象的形式,就返回的是原始类型,而不是对象。这个先前博客里有提到过。
比如typeof Number(1.1)返回结果是"number"typeof new Number("1,1"),结果是objectNumber(1.1)返回的结果是1.1。Number(123).toFixed(2);结果是123.00。

1
2
3
console.log(Number(123).toFixed(2));
console.log((100000000000).toExponential());
console.log((100000000000).toPrecision(3));

构造器函数


forEach传递给回调函数的参数

我容易把第一个和第二个写反。比如写成function(index,item)这样是不能得到正确结果的。正确的格式如下:[元素,元素索引,整个数组]

1
2
3
["a","b","c"].forEach(function(){
console.log(arguments);
})

forEach


通过JSON深拷贝

创建一个深拷贝的最简单方式,是使用JSON编码后再解码该对象,这可能不是最高效的方式,特别是在不能使用JSON的浏览器中。

1
2
3
4
5
6
7
var stuff = {
a:{
b:[1,2]
}
};
console.log(JSON.stringify(stuff));
console.log(JSON.parse(JSON.stringify(stuff)));

JSON深拷贝


构造器和类

下面的篇幅有点长,涉及到构造器,类,返回对象和this指针。

1
2
3
4
5
6
7
8
9
function Dog(){
this.name = "littleDog";
this.sayName = function(){
return this.name;
}
}

var myDog = new Dog();
console.log(myDog.sayName());

上面是一个再简单不过的我们创建的构造器函数了。我们回顾下,在我们使用new调用任何一个函数时,会发生下面的事情

1. 在后台自动创建一个空的对象,通过this引用该对象。var this = {};//伪代码,直接这样是会报错的。
2. 程序员可以给任意的this添加属性。如this.name="littleDog"。
3. 在函数的末尾,我们隐式的返回了this。return this,这不是一个错误,但是我们不需要使用它。

我们可以通过返回一个对象,从而改变步骤3,但是这个会发生下面的问题。

1
2
3
4
5
6
7
8
9
10
function Dog(){
this.name = "littleDog";

var notthis = {noname:"noname"};
return notthis;
}

var myDog = new Dog();
console.log(myDog.noname);
console.log(myDog.name);

noname, undefined这是我们会得到的结果结果,我们在这个构造器中返回了一个自定义对象,但也使用了this,当我们用返回的对象,访问对象的属性是肯定没有问题,但我们访问this定义的却是undefined。原因是:

在这个实例中,我们给this添加的任何内容,在函数返回的时候都直接销毁了,你可以删除它,并且在这种情况下,我们不需要借助new的魔力,我们可以就把它当作一般的函数调用,也可以实现相同的效果。如下:

1
2
3
4
5
6
7
8
9
10
function Dog(){
this.name = "littleDog";

var notthis = {noname:"noname"};
return notthis;
}

var myDog = Dog();
console.log(myDog.noname);
console.log(myDog.name);

这个过程中我们又要注意,如果我们返回的任何this以外的内容,都会导致instanceof运算符和constructor属性无法正常工作。

1
2
3
var myDog = new Dog();
console.log(myDog instanceof Dog);
console.log(myDog.constructor === Object);

结果是,false,true。

当我们使用new的时候,可以返回一个定制的对象,而不是this,但是它必须是一个对象,如果你尝试返回一个非对象,将导致返回值被忽略,最后还是会得到this

1
2
3
4
5
6
7
8
9
10
function Dog(){
this.name = "littleDog";
this.sayName = function(){
return "hello, "+this.name;
}
return 1;
}

var myDog = new Dog();
console.log(myDog.sayName());

这个例子里1将会被忽略。同样是返回this。但如果我们var myDog = Dog();肯定结果就是1了,对吧。


增强构造器

我们是可以通过变成来确保即便调用者忘记了new,函数也会像是构造器函数一样工作。可以使用instanceof,它接受一个对象和一个构造器函数的引用,返回true或者false。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function Dog(){
if(!(this instanceof Dog)){
return new Dog();
}

this.name = "littleDog";
this.sayName = function(){
return "hello, "+this.name;
}
return 1;
}

var myDog = Dog();
console.log(myDog.sayName());


总结

主要就是一个记录,方便以后查阅,也是给花的时间的一个交代,每次看完一个书,如果不把重点记下来,估计过了不久就又忘了,心痛。是我记忆太差了吗?明天就可以把书还回去啦,完美。感谢这本书的作者,Stoyan Stefanov。学习了。