1. 关于链式调用

  1. var sched = {
  2. wakeup: function () {
  3. console.log('Running');
  4. return this;
  5. },
  6. morning: function () {
  7. console.log('Going shopping');
  8. return this;
  9. },
  10. noon: function () {
  11. console.log('Having a rest');
  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. // 实现链式调用的关键是每次函数调用后返回this,jquery里面的链式调用原理也是如此
  28. sched.wakeup().morning().noon().afternoon().evening().night();

2. 如何访问对象的属性

  1. var myLang = {
  2. No1: 'HTML',
  3. No2: 'CSS',
  4. No3: 'JavaScript',
  5. myStudyingLang: function (num) {
  6. console.log(this['No' + num]);//直接拼接 this.No + num 会报错
  7. }
  8. }
  9. myLang.myStudyingLang(1); // 返回'HTML'
  10. //例如
  11. obj = {
  12. name: '潘小姐'
  13. }
  14. console.log(obj['name'])
  15. //访问obj.name的时候,js引擎在内部做了隐式转换 obj['name']

3. 对象枚举,一组有共同特性的数据集合叫枚举。

遍历,一组信息内,按顺序的一个一个获取其信息的过程叫做遍历的过程,有枚举就一定有遍历。

  1. var car = {
  2. brand: 'banz',
  3. color: 'red',
  4. displacement: '3.0'
  5. }
  6. for(var key in car){
  7. console.log(car.key);//返回三个undefined,原因是因为系统内置隐式转换成了car['key'],但是系统 找不到这个值,所以返回undefined
  8. console.log(car[key]);//可以打印
  9. }

for in 既可以遍历对象,也可以遍历数组,区别也不大。
用for in遍历实例化出来的对象,可以打印出自定义的包括原型链上的值和属性。

  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. if(car.hasOwnProperty(key)) {
  14. console.log('自身属性' + key + ':' + car[key]);//brand, color, displacement
  15. } else {
  16. console.log('原型链上的属性' + key + ':' + car[key]);//lang, width, name
  17. }
  18. }
  19. //hasOwnProperty,返回布尔值,只找对象自身的属性,排除掉包括原型上的不是自己的属性。
  20. var newCar = {
  21. color: 'red',
  22. brand: 'banz'
  23. }
  24. console.log('displacement' in newCar); 返回false 系统内置隐式的做了转换 newCar['displacement'] ,不打双引号会报错
  25. function Car2(){
  26. this.color = 'red';
  27. this.brand = 'banz';
  28. }
  29. Car2.prototype.displacement = '3.0';
  30. var car2 = new Car2();
  31. console.log('displacement' in car2);//true, 判断这个属性在不在 后面的值上,不排除原型

4. instanceof 判断这个对象是不是该构造函数实例化出来的(A对象的原型里到底有没有B构造函数的原型)

  1. function Tree(){}
  2. var tree = new Tree();
  3. console.log(tree instanceof Tree);//true
  4. console.log(tree instanceof Object);//true
  5. console.log([] instanceof Object);//true
  6. console.log([] instanceof Array);//true
  7. console.log({} instanceof Object);//true
  8. var a = [];
  9. console.log(a.constructor); //Array
  10. console.log(a instanceof Array);//true

5. 经验

  1. var str = Object.prototype.toString.call(a);
  2. console.log([1, 2, 3].toString());//1,2,3
  3. console.log(str);//[object Array]
  4. // Object.prototype = {
  5. // toString:function(){
  6. // this.toString();
  7. // }
  8. // }
  9. //实际上就是函数里面的this替换成了a

判断是不是数组,常用的方法 ⬇

  1. var str1 = Object.prototype.toString.call(a);
  2. if(str1 === '[object Array]'){
  3. console.log('是数组');
  4. }else{
  5. console.log('不是数组');
  6. }

6. 关于this

  1. function test(b){
  2. this.d = 4;
  3. var a = 1;
  4. function c(){}
  5. }
  6. test(123);
  7. console.log(this.d);//4
  8. console.log(window.d);//4
  9. console.log(d);//4
  10. // AO = {
  11. // arguments: [1, 2, 3],
  12. // this: window,
  13. // b: 123,
  14. // a: undefined -> 1,
  15. // c: function(){}
  16. // }
  17. //在普通函数内部,只要没有实例化这个函数,这个函数的this是默认指向的window.

构造函数的this指向

  1. function Test(){
  2. //var this = {
  3. // __proto__: Test.prototype
  4. //}
  5. this.name = '123';
  6. }
  7. var test = new Test();

//预编译的时候,AO指向window,当new Test()的时候就执行了,GO里面产生了Test和test,且当new的时候Test内部var 了this,AO内部的this就被覆盖了,形成了原型链,this就指向了实例化的对象,test在全局

  1. // AO = {
  2. // this: window --> this:{name: 123, __proto__: Test.prototype}
  3. // }
  4. // Go = {
  5. // Test: function(){},
  6. // test: {
  7. // name: 123,
  8. // __proto__: Test.prototype
  9. // }
  10. // }

7. call/apply

  1. function Person(){
  2. this.name = '张三';
  3. this.age = 18
  4. }
  5. function Programmer(){
  6. Person.apply(this);
  7. this.work = 'teacher';
  8. }
  9. var p = new Programmer();
  10. console.log(p);//Programmer {name: '张三', age: 18, work: 'teacher'}
  11. //apply把实例化出来的对象里的this将Person里面的this替换了

1.全局的this指向window

2.预编译阶段函数的this也指向window

3.call/apply改变this指向

4.构造函数的this指向实例化的对象

8.callee

  1. function test02(a, b, c){
  2. console.log(arguments.callee);//arguments.callee返回的是正在被执行的函数对象,当执行到这一 句的时候,arguments所指向的函数是谁,就返回谁
  3. console.log(test02.length);//打印该函数形参的长度
  4. console.log(arguments.length);//打印实参的长度
  5. }
  6. test02();
  7. function test_01(){
  8. console.log(arguments.callee);
  9. function test_02(){
  10. console.log(arguments.callee);
  11. }
  12. test_02();
  13. }
  14. test_01();
  15. //打印的都是两个函数的引用

9. 用递归的方式做第n位的累加

  1. function addSum(n){
  2. if(n <= 1){
  3. return 1;
  4. }
  5. return n + addSum(n - 1);
  6. }
  7. console.log(addSum(10));

//当上面的函数写成了立即执行函数,无法直接写函数名,就可以用上arguments.callee找到这个函数

  1. var res = (function(n){
  2. if(n <= 1){
  3. return 1;
  4. }
  5. return n + arguments.callee(n - 1);
  6. })(10);
  7. console.log(res);//55

10. caller 打印调用当前函数的函数引用,谁当前调用了这个函数,就返回哪个函数(严格模式下会报错),在被调用的函数打印这个函数的caller,就可以打印出谁调用了它

  1. test_03();
  2. function test_03(){
  3. test_04();
  4. }
  5. function test_04(){
  6. console.log(test_04.caller);//打印出来是test_03()整个函数
  7. }

笔试/面试题 部分

1. 壹

  1. function foo(){
  2. bar.apply(null, arguments)
  3. }
  4. function bar(){
  5. console.log(arguments);
  6. }
  7. foo(1, 2, 3, 4, 5)

//结果打印1, 2, 3, 4, 5.事实上,每个函数的执行都相当于 函数名.call(),现在是bar.apply(),apply的第一个值又是null,this指向并没有更改,arguments传的值是数组,而 bar的参数又是空的,也就是相当于给bar传值并且执行,所以是1, 2, 3, 4, 5

2. JS的typeof能返回的值有哪些, string,number,boolean,undefined,object,function

3. 叁

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

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,逗号运算符,所以肯定返回最后面的函数 ,函数typeof出来返回 function
  10. var f = (
  11. function f(){
  12. return '1';
  13. },
  14. function g(){
  15. return 2;
  16. }
  17. )();
  18. console.log(typeof f);//number,逗号运算符,所以肯定返回最后面的函数,又有括号,成为了表达式相当于f() ,typeof(2)出来返回number

5. 伍

  1. console.log(undefined == null);//true
  2. console.log(undefined === null);//fales
  3. console.log(isNaN(100));//fales
  4. console.log(parseInt('1a') == 1);//true,parseInt从头开始找,直到出现非数为止,再隐式类型转换成number,最后再parseInt
  5. function isNaN1(num){
  6. var res = Number(num) + '';
  7. if(res == 'NaN'){
  8. return true;
  9. }else{
  10. return false;
  11. }
  12. }
  13. console.log(isNaN1('123'));//false NaN不等于任何数,包括自己

6. { } == { } 等不等于?为什么不等于?怎样让它等于?

因为引用值对比的是地址
var obj = { };
obj1 = obj;
这个时候就相等

7. 柒

  1. var a = '1';
  2. function test_05(){
  3. var a = '2';
  4. this.a = '3';
  5. console.log(a);
  6. }
  7. test_05();//打印的var a = '2';
  8. new test_05();//打印的是a,不是this.a,所以还是2
  9. console.log(a);//打印this.a = '3';

8. 捌

  1. var n = 5;
  2. function test_06(){
  3. n = 0;
  4. console.log(n);
  5. console.log(this.n);
  6. var n;
  7. console.log(n);
  8. }
  9. test_06();//第一个console.log是0,第二个this.n是找外面的n所以是5,第三个还是0
  10. new test_06();//第一个console.log找自己,有肯定打印自己所以是0,实例化确实存在this,但是没有this.n这个属性,所以undefined,第三个还是0
  11. //结果返回0, 5, 0, 0, undefined, 0

作业部分

1. 写一辆车的构造函数,再写一个人的构造函数,用apply借用车的属性

  1. function Car(brand, color, displacement){
  2. this.brand = brand;
  3. this.color = color;
  4. this.displacement = displacement; //排量
  5. this.info = function(){
  6. return '排量为' + this.displacement.toFixed(1) + '的' + this.color + this.brand;
  7. }
  8. }
  9. function Person(opt){
  10. Car.apply(this, [opt.brand, opt.color, opt.displacement]);
  11. this.name = opt.name;
  12. this.age = opt.age;
  13. this.say = function(){
  14. console.log('年龄为'+ this.age + '的' + this.name + '买了一辆' + this.info());
  15. }
  16. }
  17. var p = new Person({
  18. color: '红色',
  19. displacement: 3.0,
  20. brand: 'banz',
  21. name: '潘小姐',
  22. age: 18
  23. })
  24. p.say();