ECMAScript -对象、构造函数实例化原理、包装类原理

一、对象

1.增删改查

- 创建
1、var obj1 = {}
2、var obj2 = new Object() // 不推荐用这个
3、var obj3 = new MyObj() //使用自定义构造函数,原型是构造函数的原型,构造器指向自定义的构造函数
4、Object.create(对象或者null) //创建对象,自定义原型
关于原型与原型链

- 添加属性与方法

person.name = 'jacky';  //添加属性
person.eat = function(){
	console.log("I'm eating");
}; //添加方法

- 查找、调用

person.name; //属性查找
person.eat(); //方法调用

- 修改

person.name = "jessie";

- 删除

// 删除属性
delete person.name
// 删除方法
delete person.eat

2.对象属性遍历

for…in…

  • 缺点:会包括原型上的属性
// for...in 既可以遍历对象也可以遍历数组
var arr = [1, 2, 3, 4, 5]
for (var i = 0; i < arr.length; i++){
console.log(arr[i]);// 数组也是对象(广义),只能用arr[i]访问 不能用点结构访问
}

function Person(){
this.name = 'jacky';
this.age= 30;
}
Person.prototype.country = 'China';
var person = new Person();

for (var key in person){
console.log(key);  //键名 name age country
console.log(key + ':' + person[key]);  //键名+键值
// 不能用person.key访问,因为javascript 内置的系统 会将 person.key 看做 person['key']
}

对象.hasOwnProperty()

  • 对象.hasOwnProperty(属性名) 可以排除原型上自定义的属性
for (var key in person){
  if(person.hasOwnProperty(key)){
  	console.log(key + ':' + person[key]);  //键名+键值
  }
}

二、构造函数

  • 命名:大驼峰
  • 实例化对象:通过一个构造函数实例化(new关键字)出来的两个对象之间没有关系,是完全不同的两个对象
  • 自定义构造函数
function Teacher(opt){
	this.name = opt.name;
	this.weight = opt.weight;
	this.eat = function(){
    	this.weight++;
 	};
}

实例化原理

  • 关于构造函数里的this
    1、函数仅定义,未运行的时候,this不存在
    2、函数没有实例化,仅运行时,函数里的this指向window对象
    3、函数实例化时,会隐式return this给引用实例化对象的外界变量
  • 构造函数实例化步骤
    1、创建一个空对象,作为将要 return 的对象实例。(此时对象里仅有__proto__属性)
    2、将这个空对象的原型(proto),指向构造函数的prototype属性(产生原型链)。
    3、将这个空对象的地址赋值给函数内部的this关键字。
    4、开始执行构造函数内部的代码。
    5、函数运行结束时,隐式 return this 给外界的变量
  • 关于构造函数里的return
    若在函数中手动 return 引用类型,则会取代隐式的return this
    若在函数中手动 return 原始类型,不能取代隐式的return this
function Car1(color,brand){
  this.color = color;
  this.brand = brand;
  return {};//{} [] function 等引用类型会替代 隐式的return this
}
var car1 = new Car1("red","Benz");
console.log(car1);// 输出{}

function Car2(color,brand){
  this.color = color;
  this.brand = brand;
  return 1;// number string boolean null undefined 原始类型不会替代 隐式的return this
}
var car2 = new Car2("red","Benz");
console.log(car2);// 输出 Car2 { color: 'red', brand: 'Benz' }
  • 不用new也可以实例化对象
function Car(color,brand){
  var car = {};
  car.__proto__ = Car.prototype;
  car.color = color;
  car.brand = brand;
  return car;
}
var car = Car("red","Benz");

三、包装类

Number()、String()、Boolean()可以当做转换函数来使用,也可以当做构造函数来使用

  • 三种包装类
    1、new Number() -》转换成数字对象
    2、new String() -》转换成字符串对象
    3、new Boolean() -》转换成布尔对象
    (null、undefined没有包装类)
  • 包装类VS原始值
    1、原始类型不能手动添加属性和方法
    2、包装类会将原始类型转换成对象,可以添加属性和方法
    3、包装类也可以参与运算
    -》原因:参与运算时,包装类会隐式调用valueOf()或者toString()方法,这两种方法会返回原始值,再参与运算
  • 包装类会导致两种常见情况
    1、原始值可以调用方法
    原始值可以调用toString等方法:此时系统会隐式的创造一个包装类对象并调用方法,然后再delete该对象
var num = 123;
console.log(num.toString()); //"123"
// new Number(123).toString()

2、原始值不能添加属性和方法,但添加时系统不会报错
系统会new一个包装类并添加属性/方法,由于没有对应的变量引用,系统会随之delete该对象

var a = Number("2");  //此时Number()是转换函数,将字符串转换为number
console.log(a);// 输出 2
a.len = 1;// 不会报错,引擎先new Number(2).len = 1 由于没有引用变量保存该对象 因此随之delete
console.log(a.len);// 不会报错,输出undefined , 引擎先 new Number(a)再查找len属性,但是这个包装类是新创建的,因此不存在len属性

var b = new Number("3"); //此时Number()为构造函数
console.log(b);// 输出 Number {3}
b.len = 1;
console.log(b.len);// 输出 1
console.log(b);// 输出 Number {3, len: 1}
console.log(b+1); // 输出 4,包装类可以参与运算
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值