标签:sans col microsoft ++ san isa enum mod 100%
今日鸡汤:这个世界不会因为你的付出就必须给予回报,也不会因为你以怎样的方式对待别人,就要求他人同等对待你。人活在这世上,最难的就是保持一份谦卑和平和,而这份谦卑,来源于内心的真诚和踏实的努力。
var person = new Object();
person.name = "Tom";
person.sex = "male";
person.sayHi = function (){ console.log("Hello, I‘am " + this.name); };
var person = {
name: "Tom",
sex: "male",
sayHi: function (){ console.log("Hello, I‘am " + this.name); }
}
function Person(name,sex){
this.name = name;
this.sex = sex;
this.sayHi = function (){ console.log("Hello, I‘am " + this.name); };
}
constructor
属性,指向创建该实例的构造函数constructor
属性判断实例和构造函数之间的关系构造函数为创建对象带来了方便,但是存在浪费内存的问题;比如,构造函数中有一个方法,每次创建对象的时候就会为这个方法申请内存空间,创建多个对象就需要多个内存空间
function Person(name,sex){
this.name = name;
this.sex = sex;
this.sayHello = function () { console.log("hello"); };
}
var per1 = Person("Tom","male");
var per2 = Person("Jury","famale");
function sayHello() { console.log("hello"); }
function Person(name,sex){
this.name = name;
this.sex = sex;
this.sayHello = sayHello;
}
var per1 = Person("Tom","male");
var per2 = Person("Jury","famale");
console.log(per1.sayHello == per2.sayHello); // true
var fns = {
sayHello: function(){ console.log("hello ya"); },
playGame: funciton(){ console.log("lai wan ya da ye"); }
};
function Person(name,sex){
this.name = name;
this.sex = sex;
this.sayHello = fns.sayHello;
this.playGame = fns.playGame;
}
var per1 = Person("Tom","male");
var per2 = Person("Jury","famale");
console.log(per1.sayHello == per2.sayHello); // true
console.log(per1.playGame == per2.playGame); // true
prototype
属性,指向另一个对象。prototype
对象上function Person(name,sex){
this.name = name;
this.sex = sex;
}
Person.prototype.sayHello = function(){ console.log("hello ya"); };
Person.prototype.playGame = funciton(){ console.log("lai wan ya da ye"); };
var per1 = Person("Tom","male");
var per2 = Person("Jury","famale");
console.log(per1.sayHello == per2.sayHello); // true
console.log(per1.playGame == per2.playGame); // true
原型的作用之一 : 数据共享,节省内存空间
原型的写法:
prototype
属性,该属性是一个对象。
function F () {}
console.log(F.prototype);// => object
F.prototype.sayHi = function () {
console.log(‘hi!‘);
}
(2)构造函数的 prototype
对象默认都有一个 constructor
属性,指向 prototype
对象所在函数,即构造函数。
console.log(F.constructor === F); // => true
(3)通过构造函数得到的实例对象内部会包含一个指向构造函数的 prototype
对象的指针 __proto__
。
var instance = new F();
console.log(instance.__proto__ === F.prototype) ;// => true
// `__proto__` 是非标准属性。
(4)实例对象可以直接访问原型对象成员。
instance.sayHi(); // => hi!
每当代码读取某个对象的某个属性时,都会执行一次搜索,目标是具有给定名字的属性
function Person(name){
this.name = name;
}
Person.prototype.sayName = function(){ console.log(this.name); };
function Student(age){
this.age = age;
}
Student.prototype = new Person("张三");
var stu = new Student("23");
console.log(stu.age,stu.name); // 23,张三
// 这正是多个对象实例共享原型所保存的属性和方法的基本原理
var divObj=document.getElementById("dv");
console.dir(divObj);
//divObj.__proto__---->HTMLDivElement.prototype的__proto__
//--->HTMLElement.prototype的__proto__---->Element.prototype的__proto__
//---->Node.prototype的__proto__---->EventTarget.prototype的__proto__
//---->Object.prototype没有__proto__,所以,Object.prototype中的__proto__是null
undefined
实例对象.值类型成员 = xx
)
实例对象.引用类型成员 = xx
):同上实例对象.成员.xx = xx
):
实例对象.undefined.xx = xx
)前面例子中每添加一个属性和方法就要敲一遍 Person.prototype
,为减少不必要的输入,更常见的做法是用一个包含所有属性和方法的对象字面量来重写整个原型对象:
function Person(name,age){
this.name = name;
this.age = age;
}
Person.prototype = {
type: "human",
sayHello: function (){ console.log(this.name+"*****"+this.age); }
}
// 这样做的好处就是为 `Person.prototype` 添加成员简单了,但是也会带来一个问题,那就是原型对象丢失了 `constructor` 成员。
为了保持 constructor
的指向正确,建议的写法是:
function Person(name,age){
this.name = name;
this.age = age;
}
Person.prototype = {
constructor: Person, // 手动将 constructor 指向正确的构造函数
type: "human",
sayHello: fucntion(){ console.log(this.name+"***"+this.age); }
}
所有函数都有 prototype 属性对象:
prototype
记得修正 constructor
的指向继承是指一个对象直接使用另一对象的属性和方法。
在子类继承父类的同时,可以重新定义某些属性,并重写某些方法,即覆盖父类的原有属性和方法,使其获得与父类不同的功能。同类事物具有共同性,在同类事物中,每个事物又具有其特殊性。
运用抽象的原则舍弃对象的特殊性,抽取其共同性,则得到一个适应于一批对象的类,这便是基类(父类),而把具有特殊性的类称为派生类(子类),派生类的对象拥有其基类的全部或部分属性与方法,称作派生类对基类的继承。
function Person (name, age) {
this.type = ‘human‘;
this.name = name;
this.age = age;
}
Person.prototype.eat = function(){ console.log("吃了吗?"); };
function Student (name, age) {
Person.call(this, name, age); // 借用构造函数继承属性成员
}
var s1 = new Student(‘张三‘, 18);
console.log(s1.type, s1.name, s1.age); // => human 张三 18
// 这种继承只是属性继承,不继承父类的方法
function Person (name, age) {
this.type = ‘human‘;
this.name = name;
this.age = age;
}
Person.prototype.sayName = function () {
console.log(‘hello ‘ + this.name);
};
function Student (name, age) {
Person.call(this, name, age);
}
for(var key in Person.prototype) {
Student.prototype[key] = Person.prototype[key];
} // 原型对象拷贝继承原型对象成员
var s1 = Student(‘张三‘, 18);
s1.sayName(); // => hello 张三
// 这个是浅拷贝继承
function Person (name, age) {
this.type = ‘human‘;
this.name = name;
this.age = age;
}
Person.prototype.sayName = function () {
console.log(‘hello ‘ + this.name);
};
function Student (name, age) {
Person.call(this, name, age);
}
Student.prototype = new Person(); // 利用原型的特性实现继承
var s1 = Student(‘张三‘, 18);
console.log(s1.type); // => human
s1.sayName(); // => hello 张三
总结:
函数的定义方式 : 函数声明,函数表达式,new Function
function foo(){
// 函数体
}
var foo = function() {
// 函数体
}; // 因为 foo 是变量,所以必须有 分号‘;‘
if (true) {
function f () {
console.log(1);
}
} else {
function f () {
console.log(2);
}
}
f(); // 谷歌中输出 ‘1‘,但是 IE8 中输出是 ‘2‘
为解决执行结果在不同浏览器中结果不一致的问题,可以使用函数表达式的方式。
var f;
if(true){
f = function(){ console.log(1); };
} else {
f = function(){ console.log(2); };
}
f(); // 结果都是 ‘1’
普通函数()
、构造函数new
、对象方法.
函数是对象,实例对象也是对象,实例对象中有__proto__
属性;
对象中有__proto__
属性,对象不一定是函数,函数中有prototype
属性,比如Math
中有__proto__,但是没有prototype。
this
指向的不同场景函数的调用方式决定了 this
指向的不同:
调用方式 | 非严格模式 | 备注 |
---|---|---|
普通函数中的 this | window | 严格模式下是 undefined |
构造函数中的 this | 实例对象 | |
原型对象方法中的 this | 实例对象 | |
对象方法调用 | 该方法所属对象 | 紧挨着的对象 |
事件绑定方法 | 绑定事件对象 | |
定时器函数 | window |
"use strict"; // 严格模式,类似 html:4s 中的 doctype 声明
function f1(){
console.log(this); // 非严格模式中是 window
}
f1(); // 严格模式下是 undefined,相当于有了类的方法,但是不知道是哪个类
window.f1(); // 严格模式下是 window,添加了 对象. 才知道是哪个对象
***函数也是对象:***所有函数都是 Function
的实例。
为了能在外部调用内部的 this ,例如在定时器外部备份 this 引用,然后在定时器函数内部使用外部 this 的引用,JavaScript 专门提供了一些函数方法用来帮我们更优雅的处理函数内部 this 指向问题。
call()
方法调用一个函数, 其具有一个指定的 this
值和分别地提供的参数(参数的列表)。注意:该方法的作用和 apply()
方法类似,只有一个区别,就是 call()
方法接受的是若干个参数的列表,而 apply()
方法接受的是一个包含多个参数的数组。
// 语法
fun.call( thisArg [, arg1 [, arg2 [, ...]]] );
// 参数
* `thisArg` :在 fun 函数运行时指定的 this 值;如果指定了 null 或者 undefined 则内部 this 指向 window
* `arg1, arg2, ...` :指定的参数列表
apply()
方法调用一个函数, 其具有一个指定的 this
值,以及作为一个数组(或类似数组的对象)提供的参数。注意:该方法的作用和 call()
方法类似,只有一个区别,就是 call()
方法接受的是若干个参数的列表,而 apply()
方法接受的是一个包含多个参数的数组。
// 语法
fun.apply( thisArg, [argsArray] );
// 参数
* `thisArg` : 对象
* `argsArray` :参数数组,如:fun.apply(this, [‘eat‘, ‘bananas‘]);
bind()
函数会创建一个新函数(称为绑定函数),新函数与被调函数(绑定函数的目标函数)具有相同的函数体(在 ECMAScript 5 规范中内置的call属性)。当目标函数被调用时 this 值绑定到 bind() 的第一个参数,该参数不能被重写。绑定函数被调用时,bind() 也接受预设的参数提供给原函数。
一个绑定函数也能使用new操作符创建对象:这种行为就像把原函数当成构造器。
提供的 this 值被忽略,同时调用时的参数被提供给模拟函数。
// 语法
fun.bind( thisArg [, arg1 [, arg2 [, ...]]] );
// 参数
* `thisArg` : 当绑定函数被调用时,该参数会作为原函数运行时的 this 指向。当使用new 操作符调用绑定函数时,该参数无效。
* `arg1, arg2, ...` : 当绑定函数被调用时,这些参数将置于实参之前传递给被绑定的方法。
// 返回值 :返回由指定的 this 值和初始化参数改造的原函数拷贝。
实例:
this.x = 9;
var module = {
x: 81,
getX: function() { return this.x; }
};
console.log(module.getX()); // 返回 81
var retrieveX = module.getX; // 相当于声明了一个匿名函数
console.log(retrieveX()); // 返回 9,此时"this"指向全局作用域
// 创建一个新函数,将"this"绑定到module对象
var boundGetX = retrieveX.bind(module); // 返回的是 module 中的 x
console.log(boundGetX()); // 返回 81
function getRandom(){
this.num = parseInt(Math.random() * 10 + 1);
}
getRandom.prototype.getr = function (){
//改变定时器中的this的指向,本来应该是window,现在是实例对象了
window.setInterval(this.getr2.bind(this), 1000);
};
getRandom.prototype.getr2 = function (){
console.log(this.number);
};
var r = new getRandom();
s.getr(); // 调用这个方法一次,可以不停的产生随机数字
小结:
this
的指向null
或者 undefined
则内部 this 指向 windowfunction fn(x, y, z) {
console.log(fn.length); // => 形参的个数 3
console.log(arguments); // 伪数组实参参数集合 10,20,30
console.log(arguments.callee === fn); // 函数本身
console.log(fn.caller); // 函数的调用者
console.log(fn.name); // => 函数的名字
}
function f() {
fn(10, 20, 30);
console.log(f.caller); // null
}
f();
参数
,也叫回调函数(不怎么准确)function learn(callback){
setInterval(function (){
console.log("good good learning");
callback();
},1000);
}
learn(function(){
console.log("well well sleep");
});
返回值
// 判断这个对象是不是某个类型的
var obj = {};
console.log(obj instanceof Object);
// 判断输出某个对象的数据类型
console.log(Object.prototype.toString.call(new Date())); // [object Date]
console.log(Object.prototype.toString.call([])); // [object Array]
console.log(Object.prototype.toString()); // [object Object]
function getFun(type){
return function(){ console.log(typeof type); };
}
闭包的概念 : 函数A中,有一个函数B,函数B中可以访问函数A中定义的变量或者是数据,此时形成了闭包。闭包就是能够读取其他函数内部变量的函数,即 “定义在一个函数内部的函数”。在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
闭包的模式 : 函数模式的闭包,对象模式的闭包
闭包的作用 : 缓存数据,延长作用域链
function f1() {
var num=parseInt(Math.random()*10+1);
return function () {
console.log(num);
}
} // 闭包的方式,产生三个随机数,但是都是相同的
// 如果想要缓存数据,就把这个数据放在外层的函数和里层的函数的中间位置
var f = f1();
f(); f(); f(); // 3个结果始终是一样的
var name = "The Window";
var object = {
name: "My Object",
getNameFunc: function () {
return function () {
return this.name;
}; // this 指向调用它的对象
}
};
console.log(object.getNameFunc()()); // The Window
var name = "The Window";
var object = {
name: "My Object",
getNameFunc: function () {
var that = this; // 把 object 对象保存,这样就会一直是这个对象
return function () {
return that.name;
};
}
};
console.log(object.getNameFunc()()); // My Object
沙箱:
var rnum = 10;
(function (){
function rnum(){
return Math.random()*10;
}
var rnum = rnum();
console.log(rnum);
})();
console.log(rnum); // 10
函数中调用自己,即我调我自己。
递归要有两个条件:函数体中调用自己,要有结束条件。
// 递归调用模型
function fn1() {
console.log(111);
fn2();
console.log(‘fn1‘);
}
function fn2() {
console.log(222);
fn3();
console.log(‘fn2‘);
}
function fn3() {
console.log(333);
fn4();
console.log(‘fn3‘);
}
function fn4() {
console.log(444);
console.log(‘fn4‘);
}
fn1(); // 111 222 333 444 fn4 fn3 fn2 fn1
// 求斐波那契数列
function getFibonacci(index){
if(index ==1 || index == 2){
return 1;
}
return getFibonacci(index - 1) + getFibonacci(index - 2);
} // 1 1 2(1+1) 3((1+1)+1) 5(((1+1)+1)+(1+1))
// 计算整数阶乘的递归函数
function factorial (num) {
if (num <= 1) {
return 1;
} else {
return num * factorial(num - 1);
}
} // 1 2*1 3*2*1 4*3*2*1
// 遍历 DOM 树
var root = document.documentElement; // html
function getChildren(node) {
var nodes = node.children;
for(var i=0;i<nodes.length;i++){
getNodeName(nodes[i]); // 打印节点名字
if(nodes[i].children){ // 如果节点中还有节点,就继续遍历
getChildren(nodes[i]);
}
}
}
function getNodeName(node) {
console.log("NodeName:==="+node.nodeName);
}
getChildren(root); // HEAD META TITLE BODY SCRIPT
var obj1 = {
name: "naruto",
age: 25,
team: ["Sakura", "Sasuke", "Kakashi", function () {
sex = "男";
}]
};
var obj2 = {};
function extend(a,b){
for(var key in a){
b[key] = a[key];
}
}
extend(obj1,obj2);
console.log(obj2); // {name: "naruto", age: 25, team: Array(4)}
var obj1 = {
name: "naruto",
age: 25,
team: ["Sakura", "Sasuke", "Kakashi"],
teacher: {
name1: "Iruka",
name2: "Kakashi",
name3: "Jiraya"
}
};
var obj2 = {};
function extend(a, b){
for(var key in a){
var item = a[key]; // 获取 a 对象中每个属性的值
if(item instanceof Array){
b[key] = []; // 如果是数组,b对象中添加一个新的属性,并且这个属性值也是数组
extend(item,b[key]);
}else if(item instanceof Object){
b[key] = {}; // 如果是对象类型的,那么在b对象中添加一个属性,是一个空对象
extend(item,b[key]);
}else {
b[key] = item; // 如果值是普通的数据,直接复制到b对象的这个属性中
}
}
}
extend(obj1,obj2);
console.dir(obj2);
正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。
正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。
正则表达式的作用:
常用元字符串 | 说明 |
---|---|
\d | 匹配数字 |
\D | 匹配任意非数字的字符 |
\w | 匹配字母或数字或下划线 |
\W | 匹配任意不是字母,数字,下划线 |
\s | 匹配任意的空白符 |
\S | 匹配任意不是空白符的字符 |
. | 匹配除换行符(\n)以外的任意单个字符 |
^ | 表示匹配行首的文本(以谁开始),[ ]中括号中一般表示取反 |
$ | 表示匹配行尾的文本(以谁结束) |
常用限定符 | 说明 |
---|---|
* | 重复零次或更多次 |
+ | 重复一次或更多次 |
? | 重复零次或一次 |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
{n,m} | 重复n到m次 |
其他:
[] 表示的是 : 范围, [0-9] 表示的是0到9之间的任意的一个数字
[a-zA-Z] 表示的是 : 所有的字母的任意的一个
[0-9a-zA-Z] 表示的是: 所有的数字或者是字母中的一个
| 选择两者中的一个。注意|将左右两边分为两部分,而不管左右两边有多长
() 分组 提升优先级 从两个直接量中选择一个,gr(a|e)y 匹配 gray 和 grey
[^] 匹配除中括号以内的内容
\ 转义符
[\u4e00-\u9fa5] 匹配汉字
正则表达式从左到右进行计算,并遵循优先级顺序,这与算术表达式非常类似。
运算符 | 描述 |
---|---|
\ |
转义符 |
(), (?:), (?=), [] |
圆括号和方括号 |
*, +, ?, {n}, {n,}, {n,m} |
限定符 |
^, $, \任何元字符、任何字符 |
定位点和序列(即:位置和顺序) |
| |
替换,"或"操作;字符具有高于替换运算符的优先级,使得"m |
1。创建正则表达式的两种方法
(1)通过构造函数创建对象
var reg = new RegExp(/\d{5}/); // 如果添加双引号,需要转义
console.log(reg.test("211564")); // true
(2)通过字面量的方式创建对象
var reg = /\d{5}/;
console.log(reg.text("8149912")); // true
在正则表达式中可以添加参数:
标志 | 说明 | 备注 |
---|---|---|
i | 忽略大小写 | var reg = /\d/i; |
g | 全局匹配 | |
gi | 全局匹配+忽略大小写 | var reg = /\d/gi; |
2。正则匹配
console.log(/./.test("除了回车换行以为的任意单个字符"));//true
console.log(/.*/.test("0个到多个"));//true
console.log(/.+/.test("1个到多个"));//true
console.log(/.?/.test("哈哈"));//true
console.log(/[0-9]/.test("9527"));//true
console.log(/[a-z]/.test("what"));//true
console.log(/[A-Z]/.test("Are"));//true
console.log(/[a-zA-Z]/.test("干啥子"));//false
console.log(/[0-9a-zA-Z]/.test("9cccc"));//true
console.log(/b|(area)/.test("abrea"));//true
console.log(/[a-z]{2,3}/.test("asas"));//true
3。正则提取
// 1. 提取工资
var str = "张三:1000,李四:5000,王五:8000。";
var array = str.match(/\d+/g);
console.log(array); // (3) ["1000", "5000", "8000"]
// 2. 提取email地址
var str = "123123@xx.com,ffang@valions.cn 2869312@qq.com 286669312@qq.com...";
var array = str.match(/\w+@\w+\.\w+(\.\w+)?/g);
console.log(array); //(4) ["123123@xx.com", "ffang@valions.cn", "2869312@qq.com", "286669312@qq.com"]
// 3. 分组提取
// 3. 提取日期中的年部分 2015-5-10
var dateStr = ‘2016-1-5‘;
// 正则表达式中的()作为分组来使用,获取分组匹配到的结果用Regex.$1 $2 $3....来获取
var reg = /(\d{4})-\d{1,2}-\d{1,2}/;
if (reg.test(dateStr)) {
console.log(RegExp.$1); // 2016
}
// 4. 提取邮件中的每一部分
var reg = /(\w+)@(\w+)\.(\w+)(\.\w+)?/;
var str = "123123@xx.com.cn";
if (reg.test(str)) {
console.log(RegExp.$1); // 123123
console.log(RegExp.$2); // xx
console.log(RegExp.$3); // com
console.log(RegExp.$4); // .cn
}
4。正则替换
// 1. 替换所有空白
var str = " 12D asf assf af ";
str = str.replace(/\s/g, "xx");
console.log(str); // xxxxxx12Dxxxxasfxxxxxxassfxxxxafxx
// 2. 替换所有,|,
var str = "abc,efg,123,abc,123,a";
str = str.replace(/,|,/g, ".");
console.log(str); // abc.efg.123.abc.123.a
在JavaScript中,除了5种原始数据类型之外,其他所有的都是对象,包括函数(Function)。
在说区别之前,需要先提到另外一个知识,就是 JavaScript 的原型继承。
所有 JavaScript 的内置构造函数都是继承自 Object.prototype
。
在这个前提下,可以理解为使用 new Array()
或 []
创建出来的数组对象,都会拥有 Object.prototype
的属性值。
var obj = {};// 拥有 Object.prototype 的属性值
var arr = [];//使用数组直接量创建的数组,由于 Array.prototype 的属性继承自 Object.prototype,
//那么,它将同时拥有 Array.prototype 和 Object.prototype 的属性值
可以得到对象和数组的第一个区别:对象没有数组 Array.prototype 的属性值。
数组具有一个最基本特征:索引,这是对象所没有的。
var obj = {};
var arr = [];
obj[2] = ‘a‘;
arr[2] = ‘a‘;
console.log(obj[2]); // => a
console.log(arr[2]); // => a
console.log(obj.length); // => undefined obj.length并不具有数组的可变特性
console.log(arr.length); // => 3
// length是数组的一个内置属性,数组会根据索引长度来更改length的值
// arr.length输出3,而不是1,在给数组添加元素时,并没有按照连续的索引添加,所以导致数组的索引不连续,那么就导致索引长度大于元素个数
伪数组:
var fakeArray = {
"0": "first",
"1": "second",
"2": "third",
length: 3
};
for (var i = 0; i < fakeArray.length; i++) {
console.log(fakeArray[i]); // first second third
}
var a = Array.prototype.join.call(fakeArray, ‘+‘);
console.log(a); // first+second+third
arguments
document.getElementsByTags
得到的列表)$("div")
)var arr = Array.prototype.slice.call(arguments);
Array.prototype.forEach.call(arguments, function(v) {
// 循环arguments对象
});
// push
// some
// every
// filter
// map
// ...
var obj = {
0: ‘a‘,
1: ‘b‘,
2: ‘c‘,
length: 3
};
console.log("push===="+[].push.call(obj, ‘d‘)); //push====4
console.log("slice===="+[].slice.call(obj)); // slice====a,b,c,d
[].forEach.call(obj, function (num, index) {
console.log(num); // a b c d
});
总结:
JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。那么,为什么JavaScript不能有多个线程呢?这样能提高效率啊。
单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就不得不一直等着。
"任务队列"是一个事件的队列(也可以理解成消息的队列),IO设备完成一项任务,就在"任务队列"中添加一个事件,表示相关的异步任务可以进入"执行栈"了。主线程读取"任务队列",就是读取里面有哪些事件。
所谓"回调函数"(callback),就是那些会被主线程挂起来的代码。异步任务必须指定回调函数,当主线程开始执行异步任务,就是执行对应的回调函数。
主线程从"任务队列"中读取事件,这个过程是循环不断的,所以整个的这种运行机制又称为Event Loop(事件循环)。
主线程运行的时候,产生堆(heap)和栈(stack),栈中的代码调用各种外部API,它们在"任务队列"中加入各种事件(click,load,done)。只要栈中的代码执行完毕,主线程就会去读取"任务队列",依次执行那些事件所对应的回调函数。
代码风格:
JavaScript Standard Style
Airbnb JavaScript Style Guide
校验工具:
JSLint
JSHint
ESLint
文档相关工具:
电子文档制作工具: docute
流程图工具:DiagramDesigner
标签:sans col microsoft ++ san isa enum mod 100%
原文地址:https://www.cnblogs.com/dongqunren/p/10293921.html