一、构造函数以及实例化原理
/**
* GO = {
* Car: function () {...}
* car1: {
* color: 'red',
* brand: 'Benz'
* }
* }
* AO = {
* this: {}
* }
*/
function Car(color, brand) {
/**
* this = {
* color: color,
* brand: brand
* }
*
* return this;
*/
this.color = color;
this.brand = brand;
}
var car1 = new Car('red', 'Benz');
console.log(car1.color);
原理:
实例化的对象相当于函数执行,当看到new的时候,AO会隐式生成一个this对象,然后赋值,赋值完会隐式返回this。实例化后的对象car1就可以拿到这个对象,就可以访问里面的属性了。new的作用就是改变this的指向,隐式返回this。
知道原理后,我们不通过new关键字也可以构造函数
function Car(color, brand) {
var me = {};
me.color = color;
me.brand = brand;
return me;
/**
* me = {
* color: color,
* brand: brand
* }
*/
}
var car = Car('red', 'Mazda');
console.log(car.color);
console.log(car.brand);
注意:
如果 return 的不是原始值,将会被返回,否则,隐式返回this,就相当于赋值,把之前的对象覆盖了
function Car() {
this.color = 'red';
this.brand = 'Benz';
// return {};
//return 123;
}
var car1 = new Car();
console.log(car1);
// {}
//this{}
二、包装类
1.
原始值是没有自己的属性和方法的
null、undefind不可以添加属性和方法
一般包装类有三种 new Number new String new Boolean
var a=1;//原始值
console.log(a);
var b=new Number(a);
b.len=1;
b.add=function(){
console.log(1);
}
console.log(b.len);//1
2. 包装类的运算
包装类参与运算后,得到的结果为原始值
var a=1;
console.log(a);//1
var aa=new Number(1);
console.log(aa);//Number{[[PrimitiveValue]]:1}
aa.name='aa';
console.log(aa);//Number{[[PrimitiveValue]]:1,name:"aa"}
var bb=aa+1;
console.log(bb);//2
console.log(aa)//Number{[[PrimitiveValue]]:1,name:"aa"}
3. 值的包装
var a=123;
a.len=3;
console.log(a.len);//undefined
//过程为系统自动给new Number(123).len=3 然后没地方存储 最后delete
//包装类上String有自己的length属性
var str = 'abc';
str.length = 1; //过程为系统自动给new String('str').len=1 然后没地方存储 最后delete
// str -> length
// console.log(new String(str).length)
console.log(str.length);// 3
三、面试题
//考察包装类
/**
* GO = {
* name: undefined -> 'hello' -> 'hello10'
* type: undefined -> 'string'
* }
*/
var name = 'hello';
name += 10;
var type = typeof (name);
if (type.length === 6) {
// new String(type)
// type.text = 'string'
// delete
type.text = 'string';
}
console.log(type.text); // undefined
//----------------------------------------------------------------
//闭包以及两个实例化的对象互不影响
function Test(a, b, c) {
var d = 1;
this.a = a;
this.b = b;
this.c = c;
this.f = function () {
d++;
console.log(d);
}
// return this; 形成闭包
}
var test1 = new Test();
var test2 = new Test();
test1.f();
test1.f();
test2.f();
//----------------------------------------------------------------
//这个纯纯就是预编译的问题
/**
* GO = {
* x: undefined -> 1
* y: undefined -> 0 -> 4
* z: 0 -> 4
* add: function () { return n = n + 1 } -> function () { return n = n + 3 }
* }
*/
var x = 1,
y = z = 0;
function add(n) {
return n = n + 1;
}
y = add(x);
function add(n) {
return n = n + 3;
}
z = add(x);
console.log(x, y, z); // 1, 4, 4
//---------------------------------------------------------------------
//函数是否执行以及类数组arguments的问题
function foo1(x) {
console.log(arguments);
return x;
}
foo(1, 2, 3, 4, 5); // 1,2,3,4,5
function foo2(x) {
console.log(arguments);
return x;
} (1, 2, 3, 4, 5); // 不会执行 (1, 2, 3, 4, 5)是表达式
(function foo3(x) {
console.log(arguments);
return x;
})(1, 2, 3, 4, 5); // 1,2,3,4,5
//---------------------------------------------------------------------
// 映射关系
function b(x, y, a) {
// a = 10;
// console.log(arguments[2]);
arguments[2] = 10;
console.log(a); // 10
}
b(1, 2, 3);
四、作业
写一个函数,接收任意一个字符串,返回这个字符串的总字节数
function getBytes(str) {
var str = new String(str);
var bytes = 0;
var length = str.length;
for (var i = 0; i < length; i++) {
if (str.charCodeAt(i) > 255) {
bytes += 2;
} else {
bytes += 1;
}
}
return bytes;
}
console.log(getBytes('我爱你123'));