1. 三目元算符/三元运算符
-
简写
var a = 5; if(a > 0) { console.log('大于0'); } else { console.log('小于等于0'); } 三段式简写: a > 0 ? console.log('大于0') : console.log('小于等于0');
-
运算结果赋值
var a = 5, str = ''; if(a > 0) { str = '大于0'; } else { str = '小于等于0'; } // 三目简写 var str = a > 0 ? '大于0' // 三目运算自带 return 功能 : '小于等于0'
-
加括号运算
var a = 5, str = ''; if(a > 0) { if(a > 3) { str = '大于3'; } else { str = '小于等于3'; } } else { str = '小于等于0'; } // 三目 str = a > 0 ? ( a > 3 ? '大于3' : '小于等于3' ) : '小于等于0'
-
面试题
字符串比较大小,比较的是ASCII码,第一位比完再比第二位
var str = 89 > 9 ? ( '89' > '9' ? '通过了' : '内层未通过' ) : '外层未通过'
2. 对象 拷贝/复制/克隆 clone
2.1 浅拷贝
并没有把对象里的引用值给处理了,只处理了第一层的属性,并没有处理下面的引用值
Object.prototype.num = 1; // 所有的对象都会继承这个属性
var person1 = {
name: '张三',
age: 18,
sex: 'male',
height: 180,
weight: 140,
son: {
first: 'Jenney',
second: 'Lucy',
third: 'Jone'
}
}
var person2 = {};
// 方法1:浅拷贝 遍历赋值的方式
for(var key in person1) {
person2[key] = person1[key];
}
person2.name = '李四';
person2.son.forth = 'Ben';
console.log(person1, person2);
//------------------------------
var person2 = person1;
person2.name = '李四';
console.log(person1, person2); // 因为它们指向同一个存储空间
封装成 function
Object.prototype.num = 1;
var person1 = {
name: '张三',
age: 18,
sex: 'male',
height: 180,
weight: 140,
son: {
first: 'Jenney',
second: 'Lucy',
third: 'Jone'
}
}
var person2 = clone(person1);
person2.name = '李四';
person2.son.forth = 'Ben';
console.log(person1, person2);
function clone(origin, target) {
var tar = target || {};
for(var key in origin) {
if(origin.hasOwnProperty(key)) { // 剔除原型上的属性
tar[key] = origin[key];
}
}
return tar;
}
2.2 深拷贝
拷贝之后的值怎么修改都与之前的值无关
方法1
Object.prototype.num = 1; // 所有的对象都会继承这个属性
var person1 = {
name: '张三',
age: 18,
sex: 'male',
height: 180,
weight: 140,
children: {
first: {
name: 'Jenney',
age: 12
},
second: {
name: 'Lucy',
age: 12
},
third: {
name: 'Jone',
age: 12
}
},
car: ['Benz', 'Mazda']
}
// 深拷贝
var person2 = deepClone(person1);
person2.name = '李四';
person2.children.forth = {name: 'Ben', age: 8};
person2.children.first.age = 20;
person2.car.push('ttt');
console.log(person1, person2);
function deepClone(origin, target){
var target = target || {},
toStr = Object.prototype.toString,
arrType = '[object Array]';
for(var key in origin){
if(origin.hasOwnProperty(key)) {
if(typeof(origin[key]) === 'object' && origin[key] !== null) {
toStr.call(origin[key]) === arrType ? target[key] = []
: target[key] = {};
deepClone(origin[key], target[key]);
} else {
target[key] = origin[key];
}
}
}
return target;
}
方法2
JSON.parse(JSON.stringify(person1));
// 缺点:无法拷贝方法
3. 笔试题
-
打印内容?
function test(){ console.log(foo); // undefined var foo = 2; console.log(foo); // 2 console.log(a); // 报错: a is not defined } test();
-
打印的内容?
function a(){ var test; test(); function test(){ console.log(1); } } a(); // 1
-
打印的内容?⭐
var name = '222'; var a = { name: '111', say: function(){ console.log(this.name); } } var fun = a.say; // 上面这一句相当于 var fun = function(){console.log(this.name)} fun(); // 222 a.say(); // 111 var b = { name: '333', say: function(fun){ fun(); } } b.say(a.say); // 222 b.say = a.say; b.say(); // 333
-
打印结果是什么?
function test(){ var marty = { name: 'marty', printName: function(){ console.log(this.name); } } var test1 = { name: 'test1' } var test2 = { name: 'test2' } var test3 = { name: 'test3' } test3.printName = marty.printName; marty.printName.call(test1); // test1 marty.printName.apply(test2); // test2 marty.printName(); // marty test3.printName(); // test3 } test()
-
打印结果是什么?
var bar = { a: '1' } function test(){ bar.a = 'a'; Object.prototype.b = 'b'; return function inner(){ console.log(bar.a); // a console.log(bar.b); // b } } test()();
4. 作业
-
打印结果,并分析其原因
function Foo(){ getName = function(){ // 没有经过 var 的变量,提升到全局 console.log(1); } return this; } Foo.getName = function(){ console.log(2); } // 问:怎么样才能访问到原型上面?⭐ // 答:构造函数 new 实例化了之后的对象并没有getName方法,才会访问到原型上面 Foo.prototype.getName = function(){ console.log(3); } var getName = function(){ console.log(4); } function getName(){ console.log(5); } Foo.getName(); // 2 Foo充当了一个对象,这里只是访问自己的一个属性 getName(); // 4 GO = {getName => undefined -> function(){5} -> function(){4}} // 答案是1,为什么??? Foo().getName(); // 1 Foo 中的 getName 提升到全局 ⭐ getName(); // 1 // . 运算的优先级比 new 运算的优先级高 new Foo.getName(); // 2 先执行 Foo.getName,得到结果 2,new 一个数字没有意义 // 括号的优先级比点大,括号先执行 ⭐ // 如果前面有new,函数是一个执行体,new 是跟执行体一起走的 ⭐ // 先执行new Foo(),然后在构造函数上找 getName,没找到,则去原型上找getName new Foo().getName(); // 3 // 先执行 new Foo(),然后执行原型上的 getName,得到3,这时再 new 一个数字没有意义 new new Foo().getName(); // 3
-
请用 window.prompt 接收用户输入的年份,判断是否是闰年?(用三目运算符做)
闰年:整除4或400 并且不能整除100
function isLeap(n){ return (n % 4 === 0 && n % 100 !== 0) || n % 400 === 0 ? true : false; } console.log(isLeap(2020)); console.log(isLeap(2021));