第一章
使用内置对象创建的变量(不带关键词 new),严格等于字面量
var str1 = "abc";
var str2 = String("abc");
str1 === str2; // true
typeof str1; // string
typeof str2; // string
使用 new 创建的变量,松散等于字面量,不严格等于字面量
var str1 = "abc";
var str2 = new String("abc");
str1 == str2; // true
str1 === str2; // false
typeof str1; // string
typeof str2; // object
访问基本类型的属性时,javascript 引擎会模拟创建一个临时对象来包围基本类型,属性访问之后引擎会立马丢弃这个临时对象。这正是“基本类型不是对象,但仍可以放问它的一些属性”的原因。
var str = "abc";
str.length; // 3
str.length = 4; // 为基本类型添加属性,其实是加在了临时对象上。该赋值没有意义,这行代码执行后,临时对象立刻被丢弃。
str.length; // 3
indexOf
使用方式为 str.indexOf(searchValue, fromIndex)
, searchValue
为要查询的字符串, fromIndex
第 二个参数为起始查询点。 特殊情况:
- 如果 searchValue 为空白,即
indexOf()
,searchValue 会被当做字符串 undefined 。
"0123undefined".indexOf(); // 4
- 如果 searchValue 为空字符串,结果取决于 fromIndex:
"abc".indexOf(""); // 0 如果fromIndex为空白,或者小于等于0 ,返回 0
"abc".indexOf("", 1); // 1 如果fromIndex 大于 0 且小于等于 str.length,返回 fromIndex
"abc".indexOf("", 10); // 3 如果fromIndex 大于 str.length ,返回 str.length
可以从一个 Date 减去另一个 Date,两者的差值以毫秒返回。然而如果把两个日期相加,结果是第二个日期附加到第一个日期后面的一个字符串。
如果把两个 Date 对象相除,需要把 Date 转换为毫秒值,返回相除的结果。将两个日期相乘,会返回一个非常大的毫秒值。
var firstDate = new Date();
setTimeout(function () {
var secondDate = new Date();
console.log(secondDate + firstDate); // Thu Nov 21 2019 16:40:16 GMT+0800 (中国标准时间)Thu Nov 21 2019 16:40:13 GMT+0800 (中国标准时间)
console.log(secondDate - firstDate); // 近似等于2500
console.log(secondDate * firstDate); // 2.4785011416546957e+24
console.log(secondDate / firstDate); // 1.0000000015879815
}, 2500);
lastIndexOf
是从尾部到头部进行搜索,如果给定搜索的起始位置(即第二个参数),则从起始位置向头部进行搜索,返回找到的第一个元素的索引。
var arr = ["a", "b", "c", "a"];
arr.lastIndexOf("a"); // 3 从尾到头进行搜索字母a,首先搜到索引为3的a
arr.lastIndexOf("a", 2); // 0 从索引2位置向头部进行搜索字母a,首先搜到索引为0的a
splice
方法接受到的索引如果为负数,则从末尾开始对数组/字符串操作,-n
相当于从倒数第 n 个位置进行操作。如果没有接受到第二个参数,则一直删除到底。
var arr = ["a", "b", "c"];
arr.splice(-2, 1); // ["b"] 从倒数第二个位置即字母b,删除一个元素,一共删除了字母b
arr.splice(-2); // ["b", "c"] 从倒数第二个位置即字母b,一直删除到底,一共删除了b和c
第二章
dict 模式:创建拥有一个空的原型的对象,以避免已有的属性可能会搞乱程序。
var obj = {};
var newObj = Object.create(null);
var key = "toString";
console.log(key in obj); // true 解答:toString是一个标准的Object方法
console.log(key in newObj); // false
第三章
可以通过字面值函数为函数提供一个名称,但这个名称只能在函数内部用
var fn = function name(){type of name};
fn(); // "function"
name(); // Uncaught SyntaxError 解读:函数名name只能在函数内部访问到
使用slice
和call
可以将类数组或 NodeList 转换为数组。
[].slice.call(arguments);
[].slice.call(NodeList);
第四章
继承一个对象的方式: Object.create()
、apply
function Parent() {
this.name = "js";
}
Parent.prototype.age = 24;
function Child() {}
//方式一
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
//方式二
function Child() {
Parent.apply(this, arguments);
}
让方法链化的关键一步是,在方法尾部返回对象(使用该方法的对象)的引用。
function Book() {
this.setTitle = function (title) {
this.title = title;
return this;
};
this.setAuthor = function (author) {
this.author = author;
return this;
};
}
var book = new Book();
book.setTitle("js").setAuthor("Jorn");
console.log(book.author); // Jorn
第五章
NodeList
唯一可使用的属性为 length,唯一方法为 item。不能直接对NodeList
使用 Array 方法,比如 push。
DOM 的style
属性只能获取到内联样式,style 标签以及样式表中的样式,无法通过.style
方式获取。可以使用 getComputedStyle 去获取元素所有当前生效的样式。
display:none
会从页面布局中完全删除元素,而visibility:hidden
只是视觉上隐藏了元素,仍然会影响其他元素的布局。
第八章
在 JSON 中,如果对象包含其他对象,其他对象会被转换为 JSON 的等价形式。
var obj = { name: "obj" };
var newObj = { name: "newObj", other: obj };
JSON.stringify(newObj); // "{"name":"newObj","other":{"name":"obj"}}"
第九章
向 SVG 添加 JavaScript,必须提供 style 属性。并且要把脚本包含在 CDATA 块中,否则 XML 会把<当做 XML 而不是脚本对待。
<script type="text/ecmascript">
<![CDATA[
var name = 'js';
]]>
</script>
访问 svg 元素
<object id="object" data="demo.svg"></object>
<script>
var object = document.getElementById("object");
object.onload = function () {
var svgdoc;
try {
svgdoc = object.contentDocument;
} catch (error) {
try {
svgdoc = object.getSVGDocument();
} catch (error) {
alert("SVG Not Support");
}
}
};
</script>
Math.round
中间值(0.5)向较大数取值,所以Math.round(-1.5)
为-1,而不是-2
在获取画布的 imageData 时常常会发生如下错误:Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data
增加一个img.crossOrigin = ''
即可解决这个问题。
video
元素有个timeupdate
事件,每 200 毫秒触发一次。
虽然NaN
不等于自身,但是对于使用NaN
作为键的 Map 对象,NaN
是和自身相等的:
var myMap = new Map();
myMap.set(NaN, "nan");
var key = Number("not a number");
console.log(myMap.get(key)); // 'nan'
使用数组作为键的 Map 对象,必须使用完全相同的键才能获取到响应的键值:
var arr = [1, 2];
var arr2 = arr;
var myMap = new Map();
myMap.set(arr, "12");
console.log(myMap.get([1, 2])); // undefined
console.log(myMap.get(arr2)); // '12'
第十二章
通用模块定义 UMD
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global.moduleName = factory());
}(this, function () {
'use strict';
// TODO
}
某个 package.json 文件中,用npm remove
命令移出 dependencies(或 devDependencies)中的最后一项,属性 dependencies 并不会被一并删除,只是将其设为一个空值。
"dependencies":{}
第十三章
Worker 线程的一个缺点,就是并不是所有的内建对象或功能都能在所有的浏览器中可用。比如在旧版本的 Firefox 中,异步的 FileReader 不会在 Worker 线程中工作。
第十四章
Shadow DOM,即这部分 DOM 默认与外部 DOM 隔离,内部任何代码都无法影响外部。
Web Component https://jsfiddle.net/zhaohd/vfbnLeaz/
第十五章
要使用 GET、POST 或 HEAD 之外的一个方法,必须对你的请求预检(preflight)。