1.链式操作

  1. var sched = {
  2. wakeup: function(){
  3. console.log('Running');
  4. return this;
  5. },
  6. morning: function(){
  7. console.log('Go Shopping');
  8. return this;
  9. },
  10. noon: function(){
  11. console.log('Having a reset');
  12. return this;
  13. },
  14. afternoon: function(){
  15. console.log('Studying');
  16. return this;
  17. },
  18. evening: function(){
  19. console.log('walking');
  20. return this;
  21. },
  22. night: function(){
  23. console.log('Sleeping');
  24. return this;
  25. }
  26. }
  27. sched.wakeup().morning().noon().afternoon().evening().night();

2.obj[‘xxx’]/ obj.xxx

最早的Js引擎 解析obj[‘xxx’],
会将obj.name => obj[‘name’]

  1. var myLang = {
  2. No1: 'HTML',
  3. No2: 'CSS',
  4. No3: 'JavaScript',
  5. myStudyLang: function(num){
  6. console.log(this['No' + num]);
  7. }
  8. }
  9. myLang.myStudyingLang(3);

3.对象枚举, 遍历

  1. // 数组
  2. var arr = [1, 2, 3, 4, 5];
  3. // for(var i = 0; i < arr.length; i++){
  4. // console.log(arr[i]);
  5. // }
  6. for(var i in arr){ // 同上
  7. console.log(i);
  8. }
  9. // 对象
  10. var car = {
  11. brand: 'Benz',
  12. color: 'red',
  13. displacement: '3.0',
  14. lang: '5.0',
  15. width: '2.5'
  16. }
  17. for(var key in car){
  18. // console.log(car.key); // undefined
  19. // js引擎: car.key => car['key'] => undefined
  20. console.log(car[key]); // 正确输出
  21. }

4. hasOwnProperty

  1. Object.prototype.hasOwnProperty()

方法会返回一个布尔值,指示对象自身属性中是否有指定的属性(也就是是否有指定的键).

  1. 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]); } }

  1. <a name="axLUj"></a>
  2. # ![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
  3. ```javascript
  4. var car = {
  5. brand: 'Benz',
  6. color: 'red'
  7. }
  8. console.log(color in car); // 报错
  9. console.log('color' in car); // true
  10. // 原型上的属性也会查询到
  11. function Car(){
  12. this.brand = 'Benz';
  13. this.color = 'red';
  14. }
  15. Car.prototype.displacement = '3.0';
  16. var car = new Car();
  17. console.log('displacement' in car); // true

6. instanceof

instanceof 用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上.

  1. function Car(){}
  2. var car = new Car();
  3. function Person(){}
  4. var p = new Person();
  5. console.log(car instanceof Car); // true
  6. console.log(car instanceof Object);// true
  7. console.log([] instanceof Object); // true
  8. console.log([] instanceof Array); // true
  9. console.log({} instanceof Object); // true

7. 判断对象的原型

  1. var a = [];
  2. // 方法1
  3. console.log(a.constructor);// f Array()
  4. // 方法2 instanceof
  5. // 方法3 Object.prototype.toString.call()
  6. var a = [] || {};
  7. var str = Object.prototype.toString.call(a);
  8. if(str === '[object Array]'){
  9. console.log('是数组');
  10. }else{
  11. console.log('不是数组');
  12. }
  1. //
  2. var arr = [1, 2, 3, 4, 5];
  3. // Array.prototype.toString() 返回一个字符串,表示指定的元素和数组
  4. console.log(arr.toString()); // 1, 2, 3, 4, 5
  5. // Object.prototype.toString() 返回一个表示该对象的字符串
  6. console.log(Object.prototype.toString.call(arr)); // '[object Array]'
  7. // 每个对象都有toString()方法,当该对象被表示为一个文本值时,或者一个对象以预期的字符串方式引用时自动调用.
  8. // 默认情况下,toString()方法被每个Object对象继承,如果此方法在自定义中未被覆盖,toString()返回 "[object type]", 其中type代表对象的类型
  1. var toString = Object.prototype.toString;
  2. toString.call(new Date); // [object Date]
  3. toString.call(new String);// [object String]
  4. toString.call(new Math);// [object Math]
  5. // Since JavaScript 1.8.5
  6. toString.call(undefined);// [object undefined]
  7. toString.call(null); // [object null]

8. this

  1. 全局this => window
  2. 预编译函数this => window
  3. apply/call 改变this指向
  4. 构造函数的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(){} // }

  1. ```javascript
  2. function Test(){
  3. this.name = '123';
  4. }
  5. var test = new Test();
  6. // GO = {
  7. // Test: function Test(){}
  8. // test: undefined => {
  9. // __proto__: Test.prototype,
  10. // name: '123'
  11. // }
  12. // }
  13. //
  14. // AO = {
  15. // this: window => {
  16. // __proto__: Test.prototype,
  17. // name: '123'
  18. // }
  19. // }
  20. //
  1. function Person(){
  2. this.name: '张三';
  3. this.age: 18
  4. }
  5. function Programmer(){
  6. Person.apply(this);
  7. this.work = 'Programming'
  8. }
  9. var p = new Person();
  10. console.log(p);

image.png

9. callee / caller

1. callee

  1. // arguments.callee 属性包含当前正在执行的函数
  2. // callee 是arguments 对象的一个属性.它可以用于引用该函数的函数体内当前正在执行的函数.
  3. // 这在函数的名称未知时很有用.
  4. function test(a, b, c){
  5. console.log(arguments.callee);
  6. console.log(arguments.callee.length);
  7. console.log(arguments.length);
  8. console.log(test.length);
  9. }
  10. test(1, 2);

image.png

  1. function test1(){
  2. console.log(arguments.callee);
  3. function test2(){
  4. console.log(arguments.callee);
  5. }
  6. test2();
  7. }
  8. test1();

image.png

  1. function sum(n){
  2. if(n <= 1){
  3. return 1;
  4. }
  5. return n + sum(n - 1)
  6. }
  7. var res = sum(10);
  8. console.log(10); // 55
  9. var sum = (function(){
  10. if(n <= 1){
  11. return 1
  12. }
  13. return n + arguments.callee(n - 1);
  14. })(100)
  15. console.log(sum);

2. caller 返回当前被调用函数的函数引用

  1. function test1(){
  2. test2();
  3. }
  4. function test2(){
  5. console.log(test2.caller);
  6. }
  7. test1();

image.png

10. 笔试题

  1. 案例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);

  1. ![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. 案例2
  3. ```javascript
  4. // typeof 返回多少种类型?
  5. // typeof 总是返回字符串
  6. // String, undefined, Number, null, Boolean, object, function
  7. typeof Math.LN2 === 'number';
  8. typeof Infinity === 'number';
  9. typeof NaN === 'number'; // 尽管它是 "Not-A-Number" (非数值) 的缩写
  10. typeof Number(1) === 'number'; // Number 会尝试把参数解析成数值
  11. typeof 42n === 'bigint';
  12. typeof `template literal` === 'string';
  13. typeof '1' === 'string'; // 注意内容为数字的字符串仍是字符串
  14. typeof (typeof 1) === 'string'; // typeof 总是返回一个字符串
  15. typeof String(1) === 'string'; // String 将任意值转换为字符串,比 toString 更安全
  16. typeof Boolean(1) === 'boolean'; // Boolean() 会基于参数是真值还是虚值进行转换
  17. typeof !!(1) === 'boolean'; // 两次调用 ! (逻辑非) 操作符相当于 Boolean()
  18. // 使用 Array.isArray 或者 Object.prototype.toString.call
  19. // 区分数组和普通对象
  20. typeof [1, 2, 4] === 'object';
  21. // 下面的例子令人迷惑,非常危险,没有用处。避免使用它们。
  22. typeof new Boolean(true) === 'object';
  23. typeof new Number(1) === 'object';
  24. typeof new String('abc') === 'object';
  1. 案例3

    1. // 实参和形参是相互映射的关系,你改我也改
    2. function b(x, y, a){
    3. a = 10;
    4. alert(arguments[2]); // 10
    5. }
    6. b(1, 2, 3);
  2. 案例4

    1. var f = (
    2. function f(){
    3. return '1';
    4. },
    5. function g(){
    6. return 2;
    7. }
    8. );
    9. console.log(typeof f); // funtion
    10. //--------------------------------------------------------------
    11. var f = (
    12. function f(){
    13. return '1';
    14. },
    15. function g(){
    16. return 2;
    17. }
    18. )();
    19. console.log(typeof(f)); // number
  3. 案例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’) => 会转换到非数字结束为止

  1. 6. 案例6
  2. ```javascript
  3. function isNaN(num){
  4. var res = Number(num);
  5. if(res == NaN){
  6. return true;
  7. } else{
  8. return false;
  9. }
  10. }
  11. console.log(isNaN('ABC')); // false 因为NaN不等于任何值,包括他自己
  12. //
  13. function isNaN1(num){
  14. var res = Number(num) + ''; // 将Number(num) 出来的值隐式转换为字符串的'NaN'
  15. if(res == 'NaN'){
  16. return true;
  17. } else{
  18. return false;
  19. }
  20. }
  21. console.log(isNaN1('ABC')); // true
  22. console.log(isNaN1('123')); // false
  1. 案例7

    1. {} == {} // false 因为引用值对比的是地址 两个引用值存储在不同空间
    2. // 让他们相等的办法
    3. var obj = {}
    4. obj1 = obj;
    5. console.log(obj1 == obj) // true
  2. 案例8

    1. var a = '1';
    2. function test(){
    3. var a = '2';
    4. this.a = '3';
    5. console.log(a);
    6. }
    7. test(); // 2
    8. new test(); // 2 // this 指向了全局
    9. console.log(a); // 3
  3. 案例9

    1. var a = 5;
    2. function test(){
    3. a = 0;
    4. console.log(a);
    5. console.log(this.a);
    6. var a;
    7. console.log(a);
    8. }
    9. test(); // 0 5 0
    10. new test(); // 0 undefined 0