链式调用

  1. var sched = {
  2. wakeup: function () {
  3. console.log('wakeup');
  4. return this;
  5. },
  6. morning: function () {
  7. console.log('morning');
  8. return this;
  9. },
  10. afternoon: function () {
  11. console.log('afternoon');
  12. return this;
  13. },
  14. night: function(){
  15. console.log('night');
  16. return this;
  17. }
  18. }
  19. sched.wakeup().morning().afternoon().night();

数组语法调用对象属性

  1. var myLang = {
  2. No1: 'HTMl',
  3. NO2: 'CSS',
  4. NO3: 'JS',
  5. myStudyingLang:function(num){
  6. console.log(this["NO"+num]);
  7. }
  8. }
  9. myLang.myStudyingLang(1); // HTMl
  10. myLang.myStudyingLang(2); //CSS
  11. myLang.myStudyingLang(3); // JS
  12. var obj = {
  13. name:'123'
  14. }
  15. console.log(obj.name) // 123
  16. console.log(obj['name']) // 123
  17. js引擎内部 obj.name -> obj[name]

对象属性的遍历

  1. //for in 遍历对象
  2. var car = {
  3. brand: 'Benz',
  4. color:'red',
  5. displacement:'3.0',
  6. lang:'5',
  7. width:'2.5'
  8. }
  9. for(var key in car){
  10. //遍历键名
  11. console.log(key)
  12. //遍历键值
  13. //1.错误写法
  14. console.log(car.key) // 5个undefined
  15. // console.log(car.key) => console.log(car['key']) 找不到名字为 name的属性
  16. //2.正确写法
  17. console.log(car[key]); //Benz red 3.0 5 2.5
  18. }
  19. //for in 遍历数组
  20. var arr = [1,2,3,4,5];
  21. for(var i in arr){
  22. console.log(i); // 0 1 2 3 4
  23. // 数组是特殊的对象不写键名默认0 1 2 3 嘛? 已验证是的 p15
  24. //for in同样可以遍历数组
  25. console.log(arr[i]); // 1 2 3 4 5
  26. }

image.png

hasOwnProperty

  1. function Car(){
  2. this.brand = 'Benz';
  3. this.color = 'red';
  4. this.displacement = '3.0';
  5. }
  6. Car.prototype = {
  7. lang:5,
  8. width:2.5
  9. }
  10. Object.prototype.name= 'Object';
  11. var car = new Car();
  12. for(var key in car){
  13. //打印自身的(非继承)属性
  14. if(car.hasOwnProperty(key)){
  15. console.log(car[key]); // Benz red 3.0
  16. }
  17. //in的作用 :打印对象所有属性值 包括原型链上的
  18. // console.log(car[key]);
  19. }

image.png

image.png

instanceof

  1. function Car(){}
  2. var car = new Car();
  3. function Person(){}
  4. var p = new Person();
  5. console.log(car instanceof Car);
  6. console.log(car instanceof Object);
  7. console.log([] instanceof Array);
  8. console.log([] instanceof Object);
  9. console.log({} instanceof Object);
  10. //A对象的原型里到底有没有B的原型

image.png

判断数组(对象)的方法

  1. var a = [];
  2. console.log(a.constructor);
  3. console.log(a instanceof Array);
  4. console.log(Object.prototype.toString.call(a)); //也可以判断对象
  5. //最推荐方法 Object.prototype.toString.call();
  6. var str = Object.prototype.toString;
  7. var trueTip = '[object Array]';
  8. if(str.call(a) == trueTip){
  9. console.log('是数组');
  10. }else{
  11. console.log('不是数组');
  12. }

image.png

This

  1. function Test(){
  2. // 隐式
  3. // var this = {
  4. // __proto__:Test.prototype
  5. // }
  6. this.name = '123';
  7. }
  8. var test = new Test();
  9. // AO = {
  10. // this:{
  11. // name:'123',
  12. // __proto__:Test.prototype
  13. // }
  14. // }
  15. // GO = {
  16. // Test: function test(){}
  17. // test:{
  18. // name:'123',
  19. // __proto__:Test.prototype
  20. // }
  21. // }

image.png

  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 Programmer();
  10. console.log(p);
  11. //传参写法
  12. function Person(name,age){
  13. this.name = name;
  14. this.age = age;
  15. }
  16. function Programmer(name,age){
  17. Person.apply(this,[name,age]);
  18. this.work = 'Programming'
  19. }
  20. var p = new Programmer('张三',18);
  21. console.log(p);

image.png

总结: this指向

call/apply
//全局this ->window
//预编译函数this -> window
//apply/call改变this指向
//构造函数的this指向实例化对象

callee/caller

1.callee

引用

calleearguments 对象的一个属性。它可以用于引用该函数的函数体内当前正在执行的函数。这在函数的名称是未知时很有用,例如在没有名称的函数表达式 (也称为“匿名函数”)内。https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/arguments/callee

  1. function test(a,b,c){
  2. console.log(arguments.callee.length); //此时 arguments.callee 等于 test 所以arguments.callee.length=>test.length
  3. console.log(test.length);
  4. console.log(arguments.length);
  5. }
  6. test(1,2);
  7. function test1(){
  8. console.log(arguments.callee); //arguments.callee =>test1 所以 console.log(arguments.callee)=>console.log(test1)
  9. function test2(){
  10. console.log(arguments.callee); //arguments.callee =>test2 所以 console.log(arguments.callee)=>console.log(test2)
  11. }
  12. test2();
  13. }
  14. test1();
  15. //demo
  16. 递归求累加值 一般写法
  17. function sum(n){
  18. if(n<=1){
  19. return 1;
  20. }
  21. return n + sum(n-1);
  22. }
  23. console.log(sum(10)); //50
  24. callee写法
  25. var sum = (function(n){
  26. if(n<=1){
  27. return 1;
  28. }
  29. return n + arguments.callee(n-1); // arguments.callee => 等于此立即执行函数本身
  30. })(10);
  31. console.log(sum); //50

image.png

2.caller

该特性是非标准的,请尽量不要在生产环境中使用它!
返回调用指定函数的函数.
该属性的常用形式arguments.callee.caller替代了被废弃的 arguments.caller.
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/caller

  1. test1();
  2. function test1(){
  3. test2();
  4. }
  5. function test2(){
  6. console.log(test2.caller); // test2.caller => 是谁调用的test1
  7. }

image.png

习题

1.

  1. function foo(){
  2. bar.apply(null,arguments);
  3. // 等价于=>bar(arguments);
  4. }
  5. function bar(){
  6. console.log(arguments); // 1,2,3,4,5
  7. }
  8. foo(1,2,3,4,5);
  9. // bar() -> bar.call(arguments)->bar(arguments)
  10. // 关键 bar.call(null) => bar()

image.png
引JS 方法名.call()

2. JS的typeof可能返回的值有哪些?

  1. object(null)/boolean/number/string/undefined/function

3.

  1. function b(x,y,a){
  2. arguments[2] = 10;
  3. console.log(a); //10
  4. a = 10;
  5. console.log(arguments[2]); //10
  6. }
  7. b(1,2,3);
  8. //实参与形参是--对应的关系 更改任意其中一项 另一项也会跟着更改

image.png

4.

  1. var f = (
  2. function f(){
  3. return '1';
  4. },
  5. function g(){
  6. return 2;
  7. }
  8. );
  9. console.log(typeof(f)); //function(string类型的) =>//等价于 f(f(),g()) 但g()函数未执行
  10. var f = (
  11. function f(){
  12. return '1';
  13. },
  14. function g(){
  15. return 2;
  16. }
  17. )();
  18. console.log(typeof(f)); //number(string类型的) =>//等价于 f(f(),g())() =>typeof(2)

5.isNaN原理

  1. console.log(undefined==null); //true
  2. // undefined 不大于小于等于0 null 也不大于小于等于0 所以 true
  3. console.log(undefined===null); //false
  4. // 长得不一样 所以false
  5. console.log(isNaN('100')); //true 会隐式的先 Number('100') => 100 100!=NaN 所以等于false
  6. // function isNaN(num){
  7. // var res = Number(num) + '';
  8. // if(res == 'NaN'){
  9. // return true;
  10. // }else{
  11. // return false;
  12. // }
  13. // }
  14. console.log(parseInt('1a'))==1; //true
  15. //parseInt('1a') 等于 1

6.

  1. // 1.空对象是否等于空对象 不相等
  2. // {}=={} //false
  3. // 2.为什么不相等 以为引用型数据对比的是内存地址
  4. // 3.如何让他们相等
  5. // var obj = {}
  6. // obj1 = obj
  7. // obj == obj //true

7.

  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
  9. console.log(a); //3 全局this ->window
  10. // GO{
  11. // a: undefined -> 1 -> 3
  12. // }

8.

  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();
  10. new test(); // 此时 var this = {} 没有a这个属性 所以等于空

image.png