链式调用

  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();

this是sched对象,返回sched对象,在对象中this就指代对象本身

数组语法调用对象属性

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

对象属性的遍历

键值对 key键名:value键值
for in既可以遍历对象,也可以遍历数组

  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. //遍历键名,key是键名
  11. console.log(key)
  12. //遍历键值
  13. //1.错误写法
  14. console.log(car.key) // 5个undefined
  15. // console.log(car.key) => console.log(car['key']) 找不到名字为key的属性 name的属性
  16. //因为先转换成car['key'],不是转换成car[key]
  17. //2.正确写法
  18. console.log(car[key]); //Benz red 3.0 5 2.5
  19. }
  20. //for in 遍历数组
  21. var arr = [1,2,3,4,5];
  22. for(var i in arr){
  23. console.log(i); // 0 1 2 3 4
  24. // 数组是特殊的对象不写键名默认0 1 2 3 嘛? 已验证是的 p15
  25. /* i也可以看作键名,因为数组也可以看作对象,键名从0-4 */
  26. //for in同样可以遍历数组
  27. console.log(arr[i]); // 1 2 3 4 5
  28. }

image.png

hasOwnProperty

实例对象.hasOwnProperty(key)返回true
hasOwnProperty() 方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性(也就是,是否有指定的键),不包括原型链。
hasOwnProperty对象自身不包括原型链上是否有目标属性、键名

  1. function Car() {
  2. var a=1;//不会被for in遍历,不会打印
  3. this.brand = 'Benz';
  4. this.color = 'red';
  5. this.displacement = '3.0';
  6. }
  7. Car.prototype = {
  8. lang: 5,
  9. width: 2.5
  10. }
  11. Object.prototype.name = 'Object';
  12. var car = new Car();
  13. for (var key in car) {
  14. console.log(key, car[key])
  15. }
  16. console.log('------')
  17. //会遍历prototype原型上的属性,不只是构造函数本身的属性
  18. for (var key in car) {
  19. //打印自身的(非继承)属性,继承的打印不出来,返回true
  20. if (car.hasOwnProperty(key)) {
  21. console.log(key, car[key]); // Benz red 3.0
  22. }
  23. //in的作用 :打印对象所有属性值 包括原型链上的
  24. // console.log(car[key]);
  25. }

image.png

  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. //打印自身的(非继承)属性,继承的打印不出来,返回true
  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

实例对象 instanceof xx构造函数 ,实例对象的原型链中有没有xx,包含xx吗,有true
原型链上的也算

  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)); //也可以判断对象 比instanceof好
  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

全局this指向window

  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

引用

**callee**arguments 对象的一个属性。它可以用于引用该函数的函数体内当前正在执行的函数。这在函数的名称是未知时很有用,例如在没有名称的函数表达式 (也称为“匿名函数”)内。

  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写法,因为函数名称没有了,用 arguments callee找回函数=func()执行函数
  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函数,打印test1函数
  7. }

image.png

习题

1.

  1. function foo(){
  2. bar.apply(null,arguments);
  3. // 等价于=>bar(arguments); 没有this指向问题
  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()

foo的argument传入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(f)//func g(){...} g函数
  10. console.log(f())//2
  11. console.log(typeof(f)); //function(string类型的) =>//等价于 f(f(),g()) 但g()函数未执行,没有运行结果
  12. var f = (
  13. function f(){
  14. return '1';
  15. },
  16. function g(){
  17. return 2;
  18. }
  19. )();
  20. 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')); //false 会隐式的先 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);//如果是this.a,new出来就是3
  6. }
  7. test(); //2
  8. new test(); //2 因为this.a=3 —> this{a=3} var a='2'; a=3在this对象中
  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