赋值操作的返回
最近在读一本《JavaScript DOM 编程艺术》的书,其中有一句话引起了我的好奇,假如if判断语句中存在赋值语句,则赋值语句的返回总是true。我对此结果进行了检验
var a;
//这种情况下,if判断语句中返回"good",为true
//打印"good result"
if(a = "good") {
console.log("good result");
}
//这种情况下,if判断语句中返回false,为false
//什么都不打印
if(a = false) {
console.log("good result");
}
//这种情况下,if判断语句中返回undefined,为false
//什么都不打印
if(a = undefined) {
console.log("good result");
}
//这种情况下,if判断语句中返回0,为false
//什么都不打印
if(a = 0) {
console.log("good result");
}
//这种情况下,if判断语句中返回null,为false
//什么都不打印
if(a = null) {
console.log("good result");
}
//这种情况下,if判断语句中返回{},为true
//打印"good result"
if(a = {}) {
console.log("good result");
}
//这种情况下,if判断语句中返回[],为true
//打印"good result"
if(a = []) {
console.log("good result");
}
实践是检验真理的唯一标准,由此检验到赋值操作的返回就是其本身,本身类型转换后为true,则为true;转换后为false,则为false,并不总是返回true,书中的那句话实践出是不妥当的。
模板字符串的换行功能
学模板字符串时,本来只是以为模板字符串所带来的只不过是一个外部变量引入的功能,这几天发现换行不直接写\n,直接换行编写,就可以实现换行功能
let name = "Gary",
sentence = `Hi, ${name} is my name,
I'm 25 year's old~`;
//这里打印
//Hi, Gary is my name,
//I'm 25 year's old~
console.log(sentence);
ES6类的存取函数
在ES6中实现了类的表象,虽然还是基于原型链来实现的,但是大致的功能正在向着C、Java类的方式逐渐靠近,比如类的存取函数
class Book {
constructor(name = "Gary") {
this._name = name;
}
//类的取值函数
get getBook() {
return this._name;
}
//类的存储函数
set setBook(value) {
this._name = `Hi, ${value}`;
}
}
//获取到"书"这个类的实例
let book = new Book("Yinwk");
//调用实例的取值函数
//这里打印:
//Yinwk
console.log(book.getBook);
//调用实例的存储函数
book.setBook = "yinwenkai";
//再次调用实例的取值函数
//这里打印:
//yinwenkai
console.log(book.getBook);
各类型比较运算符时的转化
if(“package” == true) console.log(“package == true”);是会打印”package == true”呢,还是不会打印呢,很多人的答案肯定是会打印,理由是:因为”package”返回true啊,所以true == true啊。请看这里判断语句中是一个比较表达式,并不是if(“package”),是需要在比较语句两边进行转化的,普通类型进行toNumber,引用类型进行valueOf或者toString之后的原始值比较
if(null == undefeind) {...} //返回true
if(undefined == null) {...} //返回true
if("package" == true) {...} //将string和boolean类型进行number转化,
//"package"转化为NaN,true转化为1,
//NaN == 1吗?答案当然是false,返回false
if("0" == false){...} //将string和boolean类型进行number转化,
//"0"转化为0,false转化为0,
//0 == 0吗?答案当然是true,返回true
if("package" == 1){...} //将string和number类型进行number转化,
//将"package"转化为NaN,1还是转化为1,
//NaN == 1吗?答案当然是false,返回false
let _obj = {name: 'Gary'},
_objAno = {name: 'Gary'};
if(_obj == _objAno){...} //将两个object类型进行valueOf方法或者toString方法的转化,哪个方法转化为原始值,就用转化为的原始值进行比较
//{name: 'Gary'}在valueOf方法转化为{name: 'Gary'},在toString方法转化为"[object Object]"
//原始值当然是valueOf方法转化的值
//{name: 'Gary'} == {name: 'Gary'}吗?答案当然是false,返回false
ES6新增Array.prototype.include
ES6数组新增了一个判断是否包含数组元素的方法,用来检索数组中是否存在某个数组元素,基本有两种方式进行检索
let number_arr = [26, 18, 10, 55, 88, 100, 38, 44];
//数组中的确包含 88 这个元素
//在这里打印:
//true
console.log(number_arr.includes(88));
//从数组下标为 5 的元素后面去寻找 88 这个元素
//在这里打印:
//false
console.log(number_arr.includes(88, 5));
ES6类型数组
在ES6中引入了一些类型数组,他们的属性以及方法和普通的数组并无二致,只是对类型做了一些限制,比如Int8Array(8位二进制补码整数)、Uint8Array(8位无符号整数)、Int16Array(16位二进制补码整数)、Uint16Array(16位无符号整数)、Int32Array(32位二进制补码整数)、Uint32Array(32位无符号整数)等等
对具有着重符的字符串数组进行排序
假如需要对具有着重符号的字符串数组进行排序,需要用localCompare
let string_arr = ["Maève", "Maeve"];
string_arr.sort(function sort_arr(a, b){
return a.localCompare(b);
});
//没有着重符号的数组元素会比有着重符号的数组元素小
//这里打印:
//["Maeve", "Maève"]
console.log(string_arr);
apply、call硬绑定小经验
function Person() {
this.name = "Gary";
this.age = 26;
console.log(this.name);
console.log(this.age);
}
let clay = {
name: "Clay",
age: 27
};
//这里充分证明了new绑定实现构造函数对象的优先级大于call或者apply硬绑定
//Person函数的this指向并没有指向clay,还保持着初始值
//而对象clay的属性name和age的值都改变为Person函数this指向的值
//在这里打印:
//Gary
//26
//Gary
//26
Person.call(clay);
console.log(clay.name);
console.log(clay.age);
function Person() {
console.log(this.name);
console.log(this.age);
}
let clay = {
name: "Clay",
age: 27
};
//这里Person函数的this指向clay
//而对象clay的属性name和age的值还是保持着初始值
//在这里打印:
//Clay
//27
//Clay
//27
Person.call(clay);
console.log(clay.name);
console.log(clay.age);
从上面的例子,我们可以得出this的绑定优先级: new绑定 > apply、call和bind硬绑定 > 普通对象软绑定 > 默认绑定,当this对象上面的属性进行定义声明,再使用apply、call或者bind硬绑定时,new绑定this对象上面的属性的优先级就大于apply、call或者bind硬绑定对象上面的属性的优先级,这时候显示的就是this对象上面的属性值,当this对象上面的属性没有进行定义声明,这时候apply、call或者bind硬绑定对象上面的属性的优先级就是最大的,这时候显示的就是硬绑定对象上面的属性的属性值