js构造函数及实例化原理、包装类

142 阅读3分钟

构造函数及实例化原理、包装类

目录

构造函数原理

包装类

练习题、面试题

课后习题

一、构造函数原理

  • 如果构造函数没有实例化,那构造函数内的this指向window
  • this在不同的实例指向不同的被实例化的对象

new 做了什么

  • new被js引擎发现后,在构造函数内创建一个this对象,这个对象内保存所有参数和方法
  • 最后会隐式return这个对象,相当于把this对象绑定在实例化上
 /* GO = {
         Car: (function)
     }
    AO = {
     this : {  只要看到执行函数前有new关键字 就会在函数AO里保存一个this对象
         color: color,
         brand: brand
     }
    }
 */
 ​
 function Car(color, brand) {
   this.color = color;
   this.brand = brand;
   this.drive = function () {
     console.log("I am running");
   };
 }
 ​
 let car = new Car(bule , Benz);
 console.log(car.color);// bule
 console.log(car.brand);// Benz
 car.drive(); // "I am running"

构造函数 return

  • 如果构造函数内手贱写了return,但你return的是原始值(Number、String、Boolean、Symbol等),那么这个实例不会被影响
  • 如果你return的是引用值(Function、Object、Array),那么这个实例最终会绑定你return出去的东西

二、包装类

  • 原始值没有自己的方法和属性,当你在给原始值用链式调用时,js引擎会帮你把这个值包装成一个对象
  • let a = 1 console.log(a.len) // undefined
  • 例如
 // 包装类
 // 原始值没有自己的方法和属性
 ​
 let a = 1; //原始值
 console.log(a); 1
 let b = new Number(a); 
 console.log(b);// 一个Number对象,里面包含1
 //JS包装类
 ​
 let a = 123;
 a.len = 3;
 //JS发现原始值增加属性会隐式包装成 new Number(123).len = 3;
 //但赋值完发现保存不了 delete 所以就删了
 console.log(a.len); // 所以等于undefined
 ​
 let str = "abc";
 console.log(str.length); //3
 //   new String()本身有.length这个属性 他能保存 所以能打印
 // 相当于console.log(new String(str).length)

nullundefined不可以设置任何的属性和方法

  • string值的.length方法也是js包装成new String后查的这个对象上的length属性

数组的截断方法

 // 数组截断方法
 let arr = [1, 2, 3, 4, 5];
 arr.length = 3;
 console.log(arr); // [1,2,3]
 {
   // 字符串不能这样
   let str = "abc";
   str.length = 2;
   console.log(str); //'abc' 还是没法保存 所以就删掉

三、练习题

练习题1

 // 练习题
 let name = "宋二娃";
 name += 10; // '宋二娃10'
 let type = typeof name; //string
 if (type.length === 6) { // true
   type.text = "string"; // 没法保存
 }
 console.log(type.text); //undefined

练习题2

 //面试题
 function Test(a, b, c) {
   let b = 1;
   this.a = a;
   this.b = b;
   this.c = c;
   function f() {
     b++;
     console.log(b); 
   }
   this.g = f;
     
 let test1 = new Test();
 test1.g(); // 2
 test1.g(); // 3
 let test2 = new Test();
 test2.g(); // 2

练习题3

 // 阿里面试题
 var x = 1,
   y = (z = 0);
 function add(n) {
   return (n = n + 1); // 预编译时这个函数被下面函数覆盖了 所以执行下面的函数
 }
 y = add(x); // 4
 function add(n) {
   return (n = n + 3);
 }
 z = add(x); // 4
 console.log(x, y, z); // 1,4,4
 /* GO = {
     x:1,
     y:0,
     z:0,
     add: function add(n){return n = n+1}-> {return n = n+3}
 } */

练习题4

 //阿里面试题2 哪个函数能输出1,2,3,4,5
 ​
 1.function foo1(x) {
   console.log(arguments);
   return x;
 }foo(1, 2, 3, 4, 5); // 这个可以
 ​
 2.function foo2(x) {
   console.log(arguments);
   return x;
 }(1, 2, 3, 4, 5); // 这个不是立即执行函数
 ​
 3.(function foo3(x) {
   console.log(arguments);
   return x;
 })(1, 2, 3, 4, 5); // 这个可以
// 阿里面试题3 

function b(x, y, a) {
  a = 10;
  console.log(arguments[2]);
}
b(1, 2, 3); // 10

四、课后作业

// ASCII码 表1 0 - 127 表二 128 - 255 长度都是一字节 单位是 byte
// UNICODE码 涵盖ASCII码 256位后就是2个字节

// 写一个函数,接受任意一个字符串,算出这个字符串的总字节数
function StrNum(string) {
  let str = string;
  let num = 0;
  for (let i = 0; i < string.length; i++) {
    if (string.charCodeAt(i) < 128) {
      num += 1;
    } else {
      num += 2;
    }
  }
  console.log(num);
}
StrNum("白境"); //4

\