纪录几个点


Object.create()

创建Object的实例有下面三种方法:

1
2
3
var o1 = Object.create(Object.prototype);
var o2 = new Object;
var o3 = {};

通过:var o4 = Object.create(null);可以创建没有原型的Object,这个对象不能使用 toString,valueOf等函数。

创建一个以另一个空对象为原型,且拥有一个属性p的对象

1
o = Object.create({}, { p: { value: 42 } })


字符串判断

在涉及其它运算符(译注:如下面的减号’-‘)时,JavaScript语言不会把数字变为字符串。

1
2
"37" - 7 // 30
"37" + 7 // "377"


单目加法运算符

将字符串转换为数字的另一种方法是使用单目加法运算符。

1
2
"1.1" + "1.1" = "1.11.1"
(+"1.1") + (+"1.1") = 2.2 // 注:加入括号为清楚起见,不是必需的。


false 判断

当传递给条件语句时,所有其他值,包括所有对象会被计算为 true 。

1
2
3
4
5
6
false
undefined
null
0
NaN
空字符串 ("")

请不要混淆原始的布尔值true和false 与 布尔对象的值true和false.

1
2
3
var b = new Boolean(false);
if (b) // this condition evaluates to true
if (b == true) // this condition evaluates to false


promise catch error

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function imgLoad(url) {
return new Promise(function(resolve, reject) {
var request = new XMLHttpRequest();
request.open('GET', url);
request.responseType = 'blob';
request.onload = function() {
if (request.status === 200) {
resolve(request.response);
} else {
reject(Error('Image didn\'t load successfully; error code:'
+ request.statusText));
}
};
request.onerror = function() {
reject(Error('There was a network error.'));
};
request.send();
});
}

for…of statement

该新特性属于 ECMAScript 2015(ES6)规范,在使用时请注意浏览器兼容性。
下面的这个例子展示了 for…of 和 for…in 两种循环语句之间的区别。与 for…in 循环遍历的结果是数组元素的下标不同的是, for…of 遍历的结果是元素的值:

1
2
3
4
5
6
7
8
9
10
let arr = [3, 5, 7];
arr.foo = "hello";

for (let i in arr) {
console.log(i); // logs "0", "1", "2", "foo"
}

for (let i of arr) {
console.log(i); // logs "3", "5", "7" // 注意这里没有 hello
}


剩余参数(rest parameters)

剩余参数语法允许将不确定数量的参数表示为数组。在下面的例子中,使用剩余参数收集从第二个到最后参数。然后,我们将这个数组的每一个数与第一个参数相乘。

1
2
3
4
5
6
function multiply(multiplier, ...theArgs) {
return theArgs.map(x => multiplier * x);
}

var arr = multiply(2, 1, 2, 3);
console.log(arr); // [2, 4, 6]


列举对象属性

从 ECMAScript 5 开始,有三种原生的方法用于列出或枚举对象的属性:

1.for...in 循环
该方法依次访问一个对象及其原型链中所有可枚举的属性。

2.Object.keys(o)
该方法返回一个对象 o 自身包含(不包括原型中)的所有属性的名称的数组。

3.Object.getOwnPropertyNames(o)
该方法返回一个数组,它包含了对象 o 所有拥有的属性(无论是否可枚举)的名称。


使用 defineProperty 为已存在的对象定义 setter

set 语法将对象属性绑定到要调用的一个函数上, 当尝试设置该属性时

1
2
3
4
5
6
7
8
9
var o = { a:0 }

Object.defineProperties(o, {
"b": { get: function () { return this.a + 1; } },
"c": { set: function (x) { this.a = x / 2; } }
});

o.c = 10 // Runs the setter, which assigns 10 / 2 (5) to the 'a' property
console.log(o.b) // Runs the getter, which yields a + 1 or 6


使用defineProperty在存在的对象上定义 getter

get 语法将一个对象属性绑定到查询该属性时将被调用的一个函数上。

1
2
3
4
var o = { a:0 }

Object.defineProperty(o, "b", { get: function () { return this.a + 1; } });
console.log(o.b) // Runs the getter, which yields a + 1 (which is 1)

defineProperty 的 getter/setter 方法就是 Vue 双向绑定的一部分机制。


判断浏览器高度

注意,navigator的信息可以很容易地被用户修改,所以JavaScript读取的值不一定是正确的。很多初学者为了针对不同浏览器编写不同的代码,喜欢用if判断浏览器版本,例如:

1
2
3
4
5
6
7
8
9
var width;
if (getIEVersion(navigator.userAgent) < 9) {
width = document.body.clientWidth;
} else {
width = window.innerWidth;
}
但这样既可能判断不准确,也很难维护代码。正确的方法是充分利用JavaScript对不存在属性返回undefined的特性,直接用短路运算符||计算:

var width = window.innerWidth || document.body.clientWidth;


几个高度

1.window对象不但充当全局作用域,而且表示浏览器窗口。

2.window对象有innerWidth和innerHeight属性,可以获取浏览器窗口的内部宽度和高度。内部宽高是指除去菜单栏、工具栏、边框等占位元素后,用于显示网页的净宽高。

3.outerWidth和outerHeight属性,可以获取浏览器窗口的整个宽高。

4.screen对象表示屏幕的信息,常用的属性有:screen.width:屏幕宽度,以像素为单位;screen.height:屏幕高度,以像素为单位;


location 对象

location对象表示当前页面的URL信息。例如,一个完整的URL:
http://www.example.com:8080/path/index.html?a=1&b=2#TOP可以用location.href获取。要获得URL各个部分的值,可以这么写:

1
2
3
4
5
6
location.protocol; // 'http'
location.host; // 'www.example.com'
location.port; // '8080'
location.pathname; // '/path/index.html'
location.search; // '?a=1&b=2'
location.hash; // 'TOP'

DOM 对象

低版本的IE<8不支持querySelector和querySelectorAll。IE8仅有限支持。


JSON.stringify

哈哈, 今天才知道 JSON.stringify 有第二个参数和第三个参数,是不是很菜。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var obj = {
"name": "小明",
"age": 14,
"skills": [
"JavaScript",
"Java",
"Python",
"Lisp"
]
};

// 传入数组,用于筛选需要得到的key和value,传入key
JSON.stringify(obj, ["name", "skills"]);

// => "{"name":"小明","skills":["JavaScript","Java","Python","Lisp"]}"

// 传入函数, 用于在序列化之前对每对键值进行处理

function convert(key, value) {
if(typeof value === "string") {
return value.toUpperCase();
}

return value;
}

JSON.stringify(obj, convert);

同样, JSON.parse 也有第二个参数,用来处理得到后的JSON串。

1
2
3
4
5
6
7
JSON.parse(obj, function (key, value) {
if(key === "name") {
return value + "小朋友";
}

return value;
})

filter

filter 一般可能我们只用第一个参数,其实还有第二个,第三个参数。

1
2
3
4
5
6
7
var arr = ['A', 'B', 'C'];
var r = arr.filter(function (element, index, self) {
console.log(element); // 依次打印'A', 'B', 'C'
console.log(index); // 依次打印0, 1, 2
console.log(self); // self就是变量arr
return true;
});

利用 filter 去除里面未定义元素或者空字符串:

1
2
3
4
5
6
7
var arr = ['A', '', null, undefined, 'R'];

var newArr = arr.filter(function (ele) {
return ele && ele.trim();
})

// => ["A", "R"]

利用 filter 去重:

1
2
3
4
5
6
7
var fruits = ['apple', 'orange', 'banana', 'apple'];

var r = fruits.filter(function (ele, index, self) {
return self.indexOf(ele) === index;
})

// => ["apple", "orange", "banana"]

利用 filter 去除偶数:

1
2
3
4
5
6
7
var arr = [1,2,3,4,5,6,7,8];

var r = arr.filter(function (ele) {
return ele % 2 !== 0;
})

// => [1, 3, 5, 7]


千万不要直接用 JS 里的 Sort

1
2
3
4
5
6
7
8
// 看上去正常的结果:
['Google', 'Apple', 'Microsoft'].sort(); // ['Apple', 'Google', 'Microsoft'];

// apple排在了最后:
['Google', 'apple', 'Microsoft'].sort(); // ['Google', 'Microsoft", 'apple']

// 无法理解的结果:
[10, 20, 1, 2].sort(); // [1, 10, 2, 20]

字符串都是按照 ASCII 码来排列,所以1,2 没问题,只是平常要注意这个地方。后面一个一定要记住 Array.sort 默认都会把元素转换为 字符串,再来排序。所以连基本的数字排序他都没做好。

但是 sort 可以传入一个 function 用来自定义排序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var arr = [10, 20, 1, 2];

// 从小到大
var r = arr.sort(function (x, y) {
if(x > y) return 1;
if(x = y) return 0;
if(x < y) return -1;
})

// sort 方法会对原数组进行修改,并且返回的也是修改后的数组
// arr => [1, 2, 10, 20]
// r => [1, 2, 10, 20]

var r = arr.sort(function (x, y) {
if(x < y) return 1;
if(x = y) return 0;
if(x > y) return -1;
})

// arr => [20, 10, 2, 1]
// r => [20, 10, 2, 1]