1.链式操作
var sched = {
wakeup: function(){
console.log('Running');
return this;
},
morning: function(){
console.log('Go Shopping');
return this;
},
noon: function(){
console.log('Having a reset');
return this;
},
afternoon: function(){
console.log('Studying');
return this;
},
evening: function(){
console.log('walking');
return this;
},
night: function(){
console.log('Sleeping');
return this;
}
}
sched.wakeup().morning().noon().afternoon().evening().night();
2.obj[‘xxx’]/ obj.xxx
最早的Js引擎 解析obj[‘xxx’],
会将obj.name => obj[‘name’]
var myLang = {
No1: 'HTML',
No2: 'CSS',
No3: 'JavaScript',
myStudyLang: function(num){
console.log(this['No' + num]);
}
}
myLang.myStudyingLang(3);
3.对象枚举, 遍历
// 数组
var arr = [1, 2, 3, 4, 5];
// for(var i = 0; i < arr.length; i++){
// console.log(arr[i]);
// }
for(var i in arr){ // 同上
console.log(i);
}
// 对象
var car = {
brand: 'Benz',
color: 'red',
displacement: '3.0',
lang: '5.0',
width: '2.5'
}
for(var key in car){
// console.log(car.key); // undefined
// js引擎: car.key => car['key'] => undefined
console.log(car[key]); // 正确输出
}
4. hasOwnProperty
- Object.prototype.hasOwnProperty()
方法会返回一个布尔值,指示对象自身属性中是否有指定的属性(也就是是否有指定的键).
- hasOwnProperty 是JavaScript中唯一一个处理属性并且不会遍历的原型链的方法 ```javascript var obj = { name: ‘xiaoye’, age: ‘32’ }
var res = obj.hasOwnProperty(‘name’); // true
// 枚举自己本身的属性 function Car(){ this.brand = ‘Benz’; this.color = ‘red’; this.displacement = ‘3.0’; }
Car.prototype = { lang: ‘5.0’, width: ‘2.5’ }
Object.prototype.name = ‘Object’;
var car = new Car(); console.log(car);
for(var key in car){ if(car.hasOwnProperty(key)){ // 只有是自身属性才进行输出 console.log(car[key]); } }
<a name="axLUj"></a>
# ![image.png](https://cdn.nlark.com/yuque/0/2022/png/26116833/1646108912472-731744d5-fb3e-4d30-824a-a3cfbcbb51ca.png#clientId=u8384ecea-2dec-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=371&id=uf9159297&margin=%5Bobject%20Object%5D&name=image.png&originHeight=557&originWidth=1237&originalType=binary&ratio=1&rotation=0&showTitle=false&size=78934&status=done&style=none&taskId=u7ccf3d61-4aed-4df8-bfee-1f4f583c843&title=&width=824.6666666666666)5. str in xxx
```javascript
var car = {
brand: 'Benz',
color: 'red'
}
console.log(color in car); // 报错
console.log('color' in car); // true
// 原型上的属性也会查询到
function Car(){
this.brand = 'Benz';
this.color = 'red';
}
Car.prototype.displacement = '3.0';
var car = new Car();
console.log('displacement' in car); // true
6. instanceof
instanceof 用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上.
function Car(){}
var car = new Car();
function Person(){}
var p = new Person();
console.log(car instanceof Car); // true
console.log(car instanceof Object);// true
console.log([] instanceof Object); // true
console.log([] instanceof Array); // true
console.log({} instanceof Object); // true
7. 判断对象的原型
var a = [];
// 方法1
console.log(a.constructor);// f Array()
// 方法2 instanceof
// 方法3 Object.prototype.toString.call()
var a = [] || {};
var str = Object.prototype.toString.call(a);
if(str === '[object Array]'){
console.log('是数组');
}else{
console.log('不是数组');
}
//
var arr = [1, 2, 3, 4, 5];
// Array.prototype.toString() 返回一个字符串,表示指定的元素和数组
console.log(arr.toString()); // 1, 2, 3, 4, 5
// Object.prototype.toString() 返回一个表示该对象的字符串
console.log(Object.prototype.toString.call(arr)); // '[object Array]'
// 每个对象都有toString()方法,当该对象被表示为一个文本值时,或者一个对象以预期的字符串方式引用时自动调用.
// 默认情况下,toString()方法被每个Object对象继承,如果此方法在自定义中未被覆盖,toString()返回 "[object type]", 其中type代表对象的类型
var toString = Object.prototype.toString;
toString.call(new Date); // [object Date]
toString.call(new String);// [object String]
toString.call(new Math);// [object Math]
// Since JavaScript 1.8.5
toString.call(undefined);// [object undefined]
toString.call(null); // [object null]
8. this
- 全局this => window
- 预编译函数this => window
- apply/call 改变this指向
- 构造函数的this指向实例化对象 ```javascript function test(b){ this.d = 3; var a = 1; function c(){} }
test(123); console.log(d); // 3 console.log(window.d); // 3 console.log(this.d) // 3
// AO = { // arguments: [123] // this: window // b: 123 // a: undefined // c: function c(){} // }
```javascript
function Test(){
this.name = '123';
}
var test = new Test();
// GO = {
// Test: function Test(){}
// test: undefined => {
// __proto__: Test.prototype,
// name: '123'
// }
// }
//
// AO = {
// this: window => {
// __proto__: Test.prototype,
// name: '123'
// }
// }
//
function Person(){
this.name: '张三';
this.age: 18
}
function Programmer(){
Person.apply(this);
this.work = 'Programming'
}
var p = new Person();
console.log(p);
9. callee / caller
1. callee
// arguments.callee 属性包含当前正在执行的函数
// callee 是arguments 对象的一个属性.它可以用于引用该函数的函数体内当前正在执行的函数.
// 这在函数的名称未知时很有用.
function test(a, b, c){
console.log(arguments.callee);
console.log(arguments.callee.length);
console.log(arguments.length);
console.log(test.length);
}
test(1, 2);
function test1(){
console.log(arguments.callee);
function test2(){
console.log(arguments.callee);
}
test2();
}
test1();
function sum(n){
if(n <= 1){
return 1;
}
return n + sum(n - 1)
}
var res = sum(10);
console.log(10); // 55
var sum = (function(){
if(n <= 1){
return 1
}
return n + arguments.callee(n - 1);
})(100)
console.log(sum);
2. caller 返回当前被调用函数的函数引用
function test1(){
test2();
}
function test2(){
console.log(test2.caller);
}
test1();
10. 笔试题
- 案例1 ```javascript function foo(){ bar.apply(null, arguments); }
function bar(){ console.log(arguments); } // bar() => bar.call(arguments) => bar(arguments) foo(1, 2, 3, 4, 5);
![image.png](https://cdn.nlark.com/yuque/0/2022/png/26116833/1646136246925-2601639e-0401-4d06-a860-40aa5f8cfa82.png#clientId=u1b4919da-923a-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=166&id=u51dd1805&margin=%5Bobject%20Object%5D&name=image.png&originHeight=249&originWidth=924&originalType=binary&ratio=1&rotation=0&showTitle=false&size=22843&status=done&style=none&taskId=u177f7015-d948-4d59-b286-9ce815104db&title=&width=616)
2. 案例2
```javascript
// typeof 返回多少种类型?
// typeof 总是返回字符串
// String, undefined, Number, null, Boolean, object, function
typeof Math.LN2 === 'number';
typeof Infinity === 'number';
typeof NaN === 'number'; // 尽管它是 "Not-A-Number" (非数值) 的缩写
typeof Number(1) === 'number'; // Number 会尝试把参数解析成数值
typeof 42n === 'bigint';
typeof `template literal` === 'string';
typeof '1' === 'string'; // 注意内容为数字的字符串仍是字符串
typeof (typeof 1) === 'string'; // typeof 总是返回一个字符串
typeof String(1) === 'string'; // String 将任意值转换为字符串,比 toString 更安全
typeof Boolean(1) === 'boolean'; // Boolean() 会基于参数是真值还是虚值进行转换
typeof !!(1) === 'boolean'; // 两次调用 ! (逻辑非) 操作符相当于 Boolean()
// 使用 Array.isArray 或者 Object.prototype.toString.call
// 区分数组和普通对象
typeof [1, 2, 4] === 'object';
// 下面的例子令人迷惑,非常危险,没有用处。避免使用它们。
typeof new Boolean(true) === 'object';
typeof new Number(1) === 'object';
typeof new String('abc') === 'object';
案例3
// 实参和形参是相互映射的关系,你改我也改
function b(x, y, a){
a = 10;
alert(arguments[2]); // 10
}
b(1, 2, 3);
案例4
var f = (
function f(){
return '1';
},
function g(){
return 2;
}
);
console.log(typeof f); // funtion
//--------------------------------------------------------------
var f = (
function f(){
return '1';
},
function g(){
return 2;
}
)();
console.log(typeof(f)); // number
案例5 ```javascript console.log(undefined == null); // true console.log(undefined === null);// false console.log(isNaN(‘100’)); // false isNaN会进行对非数字类型,Number的隐式类型转换 // Number()类型转换 Number(‘1’) === 1 Number(‘1a’) => NaN Number(‘’) === 0 Number(null) === 0 Number(‘ ‘) === 0 Number(undefined) === NaN
console.log(parseInt(‘1a’)); // false parseInt(‘1a’) => 会转换到非数字结束为止
6. 案例6
```javascript
function isNaN(num){
var res = Number(num);
if(res == NaN){
return true;
} else{
return false;
}
}
console.log(isNaN('ABC')); // false 因为NaN不等于任何值,包括他自己
//
function isNaN1(num){
var res = Number(num) + ''; // 将Number(num) 出来的值隐式转换为字符串的'NaN'
if(res == 'NaN'){
return true;
} else{
return false;
}
}
console.log(isNaN1('ABC')); // true
console.log(isNaN1('123')); // false
案例7
{} == {} // false 因为引用值对比的是地址 两个引用值存储在不同空间
// 让他们相等的办法
var obj = {}
obj1 = obj;
console.log(obj1 == obj) // true
案例8
var a = '1';
function test(){
var a = '2';
this.a = '3';
console.log(a);
}
test(); // 2
new test(); // 2 // this 指向了全局
console.log(a); // 3
案例9
var a = 5;
function test(){
a = 0;
console.log(a);
console.log(this.a);
var a;
console.log(a);
}
test(); // 0 5 0
new test(); // 0 undefined 0