JavaScript 对象 构造函数 包装类篇

1. 对象:

对象就是一种基本的变量类型,他和数组、function 等等, 这些都属于引用值。对象里有一些属性和方法,他们之间可以互相更改。
(1)例如:
var myCar = {
	brand:"BMW",
	age:3,
	color:red,
	health:100,
	drive:function (){
		health--;
		console.log(health--)
	}
	maintain:{
		health++;
		console.log(health++)
	}
}

例如上边的,对象里的格式是先写属性名,加一个冒号,后边写上属性值(当然属性名后边也可以跟上一个 function 方法),中间用逗号隔开。上例是一个描述汽车的对象,此时调用 myCar.brand(品牌) 可得 “BMW” (它的age,color,health同理可得),当调用 myCar.drive(行驶)则它的健康值自减1并打印输出健康值,当调用 myCar.maintain(保养)则它的健康值自增1并打印输出健康值。

(2)属性的增删改查:我们继续用上边的例子来讲

增:如果需要给一个对象增加一个属性,就直接对象.xxx=xxx 即可,例如:myCar.weight = 1400;这样这个属性就加到对象里边了。
删:如果需要删除对象的一个属性,我们需要用到一个关键字叫 delete,delete 后边跟上对象的属性即可,例如:delete myCar.age;你再去访问 mrCar.age 就会得到 undefined(注意:变量未经声明就使用肯定报错,但是在对象里不会报错,而且输出 undefined,比如你访问 mrDeng.abc 就得到 undefined)
改:就是重新赋值,即重新赋值,比如 myCar.age = 5;
查:就是查看、访问这个属性。

(3)对象的创建方法:

第一种:plainObject 对象字面量/对象直接量。
这种方法就是直接 var obj = {…}

第二种:构造函数创建方法
例1:系统自带的构造函数 Object :

这个 Object 就是一个系统自带的函数,这个函数可以执行,Object()就可以执行这个函数,但是这样执行没啥用,我们想利用这个函数产生对象的话,必须在系统自带的构造函数执行前边加个 new,即 new Object(),这样在 new 后边加上一个构造函数方法的执行他就可以产生一个实实在在的对象,在这个方法执行的时候当然有个返回值, 所以我们在外部 var 一个变量来接收他,如 var obj = new Object(),其实这种方法和对象字面量的创建方法是一样的,后期如果我们要加东西的话,直接在后面写,如 obj.name = “abc”即可(等号和冒号区分开,冒号是写在大括号里的,大括号外边用等号)。构造函数在每次调用的时候都会产生一个对象,产生的多个对象都是一样的,而且彼此是独立的。

例2:自定义构造函数

function Person(){ } 
var person = new Person(); 

这样的话我们就创建了一个构造函数,构造函数其实和普通函数没有区别,但是我们想让构造函数产生对象的话,必须借用 new 操作符才能产生一个空对象,和上边的是 一样的。
构造函数命名规则:由于和普通函数没有任何区别,所以我们在命名的时候把他们区分开,遵循大驼峰式命名规则,就是所有的单词首字母都要大写。

例3:

function Car(color){
	this.color = color;
	this.name = "BMW";
	this.height = "1400";
	this.lang = "4900";
	this.weight = 1000;
	this.health = 100;
	this.run = function(){
		this.health--;
	}
}

解析:假如说我们在下边写上 var car = new Car();的话,我们在外部访问变量 car 就会得到一个对象,对象里有设定好的 name、height、lang 等属性,这种方式就是用 this.的方式来构造的,这里的 this 也可以理解成第一人称。我们在底下继续写上 var car1 = new Car();这就是通过同一个构造函数产生的两个不同的对象,我们在浏览器访问 car 和 car1 会得到同样的结果,属性相同,但是 car 和 car1 是两个人,属性不可以互通,比如说我们在下边写上 car.name = ‘Masarati’;car1.name = ‘Merz’;我们访问 car 就会得到 Car{color: undefined, name: “Masarati”, height: “1400”, lang: “4900”, weight: 1000, …},访问 car1 就会得到 Car{color: undefined, name: “Merz”, height: “1400”, lang: “4900”, weight: 1000, …},所以说同一个构造函数生产的不同对象是两个人,彼此独立的,互不影响,再比如我们调用 car.run();再访问 car.health 就是 99,但是我们访问 car1.health 就是 100,两个对象虽然才开 始属性相同,但是我们在后来通过不断调用自身的方法来改变自己的属性后,两个对象会变得很不一样。我们函数里传了一个形参 color,在函数里第一行的时候我们让 color 属性等于形参 color,在外部调用的时候传参:var car = new Car(‘red’);var car1 = new Car(‘green’);此时我们访问 car.color 就是 red,访问 car1.color 就是 green。

例4:

function Student(name,age,sex){
	this.name = name;
	this.age = age;
	this.sex = sex;
	this.grade = 2018;
}
var student = new Student("张三","18","male");

解析:此时我们访问 student 就会得到

student{
	name: "zhangsan",
	age: 18, 
	sex: "male", 
	grade: 2018
}

有三个是我们自己选配的,有一个是固定好了的,有选配有固定好了的就可以产生对象,并且对象和对象之间是独立的,调用多次构造函数可以产生多个独一无二的对象。

(4)构造函数的内部原理 :

为什么构造函数里加上一个this他就能生产出来对象?this为啥放到构造函数内部依然好使?其实他内部有一个三段式(都是隐式的),但是在执行的时候前边必须加上 new 才可以。下面介绍隐式的三段式:
1)在函数的最前边隐式的加上 this = {};(空对象)
2)执行 this.xxx = xxx;
3)在最后隐式的返回 this (return this)
我们来写个例子,隐式的注释掉哈:

function Person(name,height){
	//var this = {};
	this.name = name;
	this.height= height;
	this.say = function(){
		console.log(this.say);
	}
	//return this;
}
console.log(new Person("小王",180).name);

我们在外部通常 var 一个变量来接收他,但是我们现在直接把他打印出来也可以,输出得 xiaowang 那我们现在已经知道原理了,我们现在来模拟一下构造函数:

function Person(name,height){
	var that = {};
	that.name = name;
	that.height = height;
	return that;
}
var person1 = Person("小王",180);
var person2 = Person("小张",175);

既然我们模拟出来了,都是显式的定义和返回,就不用 new 了,但是我们一般不这么用,因为这里边还有很多东西是我们模拟不了的。 现在我们回归到上边的隐式的:

function Person(name,height){
	//var this = {};
	this.name = name;
	this.height= height;
	this.say = function(){
		console.log(this.say);
	}
	//return this;
}
var person1 = new Person("小王",180);
var person2 = new Person("小张",175);

假如我们显示的返回一个空对象,这就成了捣乱了,再访问 person 就得到空对象,因为它是显式的。但是:

function Person(name,height){
	//var this = {};
	this.name = name;
	this.height= height;
	this.say = function(){
		console.log(this.say);
	}
	return 123;
	//return this;
}
var person1 = new Person("小王",180);
var person2 = new Person("小张",175);

假如我们显式返回 123 的话,在访问 person 的话就会得到 Person{name: “小王”, height: 180, say: ƒ},是因为系统规定了有 new 的话就不能返回原始值,必须返回引用值,返回原始值的话系统会自动忽略。

1. 包装类:

我们知道,var num = 123,这个 num 属于原始值的 123,原始值是不能有属性和方法的,属性和方法是对象(这里的对象指的是对象、数组和 function)独有的东西,原始值只是一个值,他作为一个独立的个体存在。然而数字不全是原始值,只有原始值的数字才是原始值,在我们 js 里边,数字分两种数字,字符串分两种字符串,比如:
var num = new Number(123);
前边都加上 new 了,他就是构造函数所产生的对象,他就属于对象类型的 123,你输出 num 就会得到 Number{123},既然是对象了,就可以加属性了,比如:num.abc = ‘a’; 你在访问 num 就得到 Number{123, abc: “a”},他成了对象了,但是依然可以参与运算, 比如 num * 2 就得 246,但是参加完运算之后这个 246 又变成原始值的数字了。但是你不让他参与运算,给他加个属性或者方法,他又能当对象那么来用。字符串和布尔类型完全一致。比如:

var str = new String("abcd");
str.a = "bcd";
str.sayValue = function (){
	renturn this.a;
}

我们 console.log(str.sayValue());就会得到 bcd。你想让对象类型的数字(或者字符串)有什么值就直接在后边的括号里边写即可。还有布尔类型:

var bol = new Boolean("true");

我们访问 bol 就得到 Boolean{true},但是 undefined 和 null 他俩不可以有属性,你访问 undefined.abc = 123 或者 null.abc = 123 就会报错。知道了这些,我们就来讲包装类,比如:var str = “abcd”这是一个原始值,但是我们访问 str.length 就会得到 4,这是为啥?人家明确规定原始值是没有属性和方法的,那么这个 length 是哪来的?我们在下边继续写上 str.abc = “a”,这理论上是不可以的,因为原始值不能有属性,但是你会发现不报错,而且你访问 str.abc 得到 undefined,这又是为啥?再比如:

var str = "abcd";
str.length = 2;
console.log(str);

这时应该输出 abcd,因为在第二步的时候他会隐式的 new String(‘ abcd’) .length = 2,然后 delete 扔了,你在第三行访问 str 的时候访问的是第一行的 abcd,第二行新建的和第一行没有关系啊,而且新建完就被销毁了。所以第三行访问的是第一行的 str。
如果在下面写上 console.log(str.length);就会得到 4,因为 .length 是系统自带的属性,但是是对象的 length 属性,你访问的时候系统就隐式的 new String (‘ abcd’) .length,这个对象原本就有 length 属性是 4,所以我们会产生一种错觉, 其实你访问 str.length 就是对象的 length 属性给你抛回来的值。所以表面上看原始值可以操作属性,实际上是操作不了的。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山大王杨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值