new Promise((then, catc) => {
catc("777"); // 这两个函数之一虽然被多次调用后,但是最终只有最前调用那个会被执行
catc("778");
then("666");
then("667");
console.log("abc"); //会被最终输出
}).catch(err => {
console.log(err);
return new Promise((resolve, reject) => {
resolve("hello world")
})
}).then(value => {
console.log(value); //当返回一个新的promise,之后的链式操作都将在这个promise上,默认返回原来的Promise
});
//最终返回的仍然是promise对象
!注意:有时也可以把catch部分合并到then中,这里就成了then(val=>{}, err=>{})
我们知道,回调函数嵌套的层数多了之后代码很不美观。而
所谓promisify
, 即把一个回调函数变成promise调用的形式,这种形式如下代码#1
行所示。
//异步函数
function readFile(filename, callback) {
callback(filename + "-data");
}
//Promise化函数
function promisify(fn) {
return function (filename) {
return new Promise((resolve, reject) => {
fn(filename, function (ret) {
resolve(ret);
});
});
}
}
//使用
readFileSync = promisify(readFile);
readFileSync("123.txt").then(val => { //#1
console.log("result:" + val);
});
class Person{
constructor(name, sex) {
this.name = name;
this.sex = sex;
}
}
let obj1 = new Person("abc", 1);
let obj2 = new Person("abc", 1);
let obj3 = obj1;
console.log(obj1 == obj2)
console.log(obj1 === obj2)
console.log(obj1 == obj1)
console.log(obj1 === obj1)
console.log("123" == 123)
console.log("123" === 123)
console.log("123" === "123")
题目:请写一个闭包函数add2(),第一次调用时输出2,第二次调用时输出4,第三次调用时输出6,以此类推。
//这是闭包
function pack() {
let a = 0;
//这是闭包函数add2()
return function () {
a += 2;
return a;
}
}
const add2 = pack();
console.log(add2())
console.log(add2())
console.log(add2())
console.log(add2())
学者曰:一个函数能够保存自己定义时所处的全局环境,这个全局环境就是一个闭包。在函数pack()
执行完后,有一个匿名函数被返回,如果想要此匿名函数正常执行,js引擎必然要保存此函数定义时的环境,因此变量a
不能够立即清除,这就形成了闭包。在add2()
函数定义时,它的上层变量a
对它而言是全局的,所以这个函数变得不纯,每次add2函数的执行都是对闭包内同一个数字对象进行加2,然后返回该对象。于是我们看到这个函数每次执行后都返回不一样的值。
(1) max函数默认返回负无穷,min函数默认返回正无穷。无穷,在js里面是一个常量 Infinity
console.log(Math.max())
console.log(Math.min())
console.log(Infinity)
console.log(-Infinity)
console.log(018 - 017) //等价于 18 - 15 = 3
console.log(0x18 - 017)
在js里,函数或变量的使用
在定义
之前,依然不会报错,这叫提升
,因为js引擎将它们的定义默认提升到了最前面。在目前的js中,有且只有以下情况会提升:
//var function 会被提升,属于 function scope
//let const class都不会提升,属于block scope
//function表达式 箭头函数这种临时对象不存在scope和提升的问题
console.log(varBoost);
console.log(funcBoost);
var varBoost = 3;
function funcBoost() {
return ("func!")
}
字符串翻转
a = "123"
a = a.split("").reverse().join("") //注意这里的assign
console.log(a)
数字方法
https://www.w3school.com.cn/jsref/jsref_obj_number.asp
字符串方法
https://www.w3school.com.cn/jsref/jsref_obj_string.asp
数组与传统字典方法
https://www.w3school.com.cn/jsref/jsref_obj_array.asp
//定义
a = [];
//赋值
a["a"] = 1
a["b"] = 2
a[true] = 3
a[false] = 4;
//取值
a[true];
//删除
delete a['a']
console.log(a)
console.log(a['55'])
//遍历key-value(Object支持些操作)
for (let i in a) {
console.log(i + "=>" + a[i])
}
//[ES6]仅仅遍历value(Object不支持此操作)
for (let i of a) {
console.log(i)
}
//[ES6]定义字典
//a = new Map();
a = new Map([[true, 1], [false, 2]])
a.set("name", "abc")
a.set("sex", "def")
a.delete("sex")
console.log(a.get("name"))
console.log(a.get("sex"))
console.log(a)
console.log("size: " + a.size)
for (let i of a) { //不支持for-in
console.log(i);
}
for (let i of a.keys()) {
console.log(i);
}
//[ES6]定义集合
//b = new Set()
b = new Set([1, 2, 3, 3])
b.add(4)
b.add(4)
b.delete(1)
console.log(b)
console.log("size: " + b.size)
for (let i of b) { //不支持for-in
console.log(i);
}
console.log(typeof true)
console.log(typeof false)
console.log(typeof "true")
console.log(typeof 123)
console.log(typeof [])
console.log(typeof {})
console.log(typeof /abc/g);
console.log(typeof undefined);
console.log(typeof null);
console.log(typeof NaN);
function OBJ() { return this; };
var a;
var b = null;
var c = 123;
var d = "456"
var e = new OBJ();
console.log(Array.isArray([])) // 判断数组。 此外还有:console.log(arr instanceof Array) ;console.log(arr.constructor === Array)
console.log(isNaN(NaN)) // 判断非数字
console.log(a === undefined) // 判断undefined
console.log(b === null) // 判断null
console.log(typeof c == "number" && !isNaN(c)) //判断数字
console.log(typeof d == "string") //判断字符串
console.log(e instanceof OBJ) //判断类型
console.log(OBJ instanceof Function) //判断是否是函数
//两种特殊的函数
console.log(function () { } instanceof Function)
console.log((() => { }) instanceof Function)
function sum() {
}
console.log("*-------------------example1-------------------*")
console.log(sum)
console.log(sum.prototype)
console.log(sum.prototype.constructor)
console.log("*-------------------example2-------------------*")
let anonymous = { func: function() { } }
let b = anonymous.func
console.log(b)
console.log(b.prototype)
console.log(b.prototype.constructor)
console.log(b.__proto__)
console.log(b.__proto__ === Function.prototype)
console.log(new b().__proto__ === b.prototype)
console.log("*-------------------example3-------------------*")
let lambda = (() => { })
console.log(lambda.prototype)
console.log(lambda.__proto__)
console.log(lambda.__proto__ === Function.prototype)
略
传统Js有主要三种继承方式:
可以参考以下资料:
https://www.jb51.net/article/103729.htm
https://www.cnblogs.com/ranyonsue/p/11201730.html
事实上,在ES6中有class,这些方法都已废弃,更简洁的方法如下:
class Pa {
constructor(name) {
this.name = name;
}
sayHi() {;
console.log("Hi! my name is " + this.name);
}
complain() {
console.log("Why are you are so stupid?");
}
}
class Son extends Pa {
constructor(name, nickname) {
super(name);
this.nickname = nickname;
}
sayHi() {
super.sayHi();
console.log("my nickname is " + this.nickname);
}
}
let son = new Son("Xuezhe", "researcher");
son.sayHi();
son.complain();
try {
throw new Error("I am an error!");
} catch (e) {
console.log(e)
} finally { //无论是否异常都会执行
console.log(666);
}