任何数据都有两种定义方式:
1.字面量方式 - 定义好以后一眼就能看透
字面量方式,就是直接定义,让我们可以一目了然的看出,这个数据的类型。例如:
var num = 10
var str = 'abcdef'
var bool = true
...
2.构造函数方式 new XXX 构造一个对象 - 任意数据都可以是对象
var arr = new Array()
var obj = new Object()
var num = new Number()
var str = new String()
...
这种通过new的方式来定义对象的方式,就叫做构造函数方式。
这种方式定义的数据,也是可以像字面量方式定义的数据一样,进行数学运算、字符串拼接等操作的。例:
```
var num = new Number(10)
num += 5
console.log(num) // 15
var str = new String('abcd')
str += 'ef'
console.log(str) // 'abcdef'
```
这也就造成了,在js中,对象是无所不能的,无
例如:字符串有方法,数字也有方法
字符串.startsWith()
数字.toFixed()
let fn = function() {}
console.log(fn);
console.dir(fn)
二、面向对象
1、介绍
面向:脸面朝向
对象:js的重要组成部分
连在一起,就是脸面要朝向对象,也就是要重视对象。
面向对象是一种更加注重对象编程思想,是一种超脱的、高级的编程思想。
用专业术语来讲,面向对象又叫做OOP(Object Oriented Programming)
我们之前的编程思想叫做面向过程编程思想POP(Procedure Oriented Programming)。
2.比较
面向对象并不是一种新的语法
面向对象是一种高级的编程思想
我们平常所使用的编程思想不是对象,是面向过程
我们之前编程的思想更加注重过程,没有更加注重对象
3、创建对象
既然要面向对象,更加注重对象,就要先明白如何创建对象是最好的方式,如何给对象添加属性和方法才是最好的方式。
直接创建:
var obj = {}
构造函数方式创建:
var obj = new Object();
Object是一个系统提供的构造函数,这个构造函数专门用来创建对象使用的。 如下:保存多个人的信息,需要这样创建多次。
var obj1 = {
name: '张三',
age: 12,
sex: '男'
}
var obj2 = {
name: '李四',
age: 13,
sex: '女'
}
var obj3 = {
name: '王五',
age: 11,
sex: '女'
}
。。。
从上面的代码可以看出来,每次创建对象都是在重复动作
这时候,应该用函数来处理重复动作
4.面向对象有三大特点:
1.封装性 - 对象
2.继承性
3.多态性
4、工厂函数
定义一个函数,每次调用都能得到一个对象
function createObj(name,age,sex){
var obj = {
name,
age,
sex
}
return obj;
}
var obj1 = createObj("张三",12,"男");
var obj2 = createObj("李四",13,"女");
var obj3 = createObj("王五",11,"女");
这种调用就能创建对象的函数,叫做工厂函数。创建出来的每个对象的结构一致,如:电商网站中的商品对象。
优点:可以同时创建多个对象
缺点:输出后无法立马看出对象的类别;创建出来的没有具体的类型(比如是Array和Number),都是object类型的,但我们看到自己的对象只是object,不知道具体是什么类型。
代码:
function factory(name,age){
var obj = new Object();
obj.naem = name;
obj.age = age;
return obj;
}
var zs = factory("张三",12);
var ls = factory("李四",20);
console.log(zs);
console.log(ls);
效果:
函数解决重复
// function createObj(name, gender, age) {
// let obj = {
// name: name,
// gender: gender,
// age: age
// }
// return obj
// }
// 使用对象创建对象
// let wc = createObj('汪晨', '男', 11)
// let xl = createObj('胡小龙', '男', 12)
// let zsl = createObj('张胜澜', '女', 18)
5、构造函数
构造函数:专门用来创建对象的函数
语法:
new 函数() - 返回一个对象
从使用构造函数方式来看数字类型、字符串类型。。。
当我们定义好不同的数据,从外观上就能看出,这个数据的具体类型,例:
var arr = new Array();
var obj = new Number();
var str = new String();
console.log(arr);
console.log(obj);
console.log(str);
输出结果:
这种专门用于new来创建对象的函数,叫做构造函数。
Number、String这种函数,除了可以用new创建对象外,还可以进行类型转换。
其实这样用new创建对象的函数,我们自定义的函数也是可以的:
function fn() {}
var f = new fn()
console.log(f)
图示:
每个函数都可以这样做。当一个函数被用new来创建对象的时候,这个函数就叫做构造函数了。
通过上面代码,我们发现,如果使用自己定义的函数来创建对象的话,就可以立马看到这个对象的具体类型了。
所以,解决工厂函数的问题,就可以使用自定义的构造函数来实现。
例:
function Person(){
}
var zs = new Person();
function fn(){
}
var ls = new fn();
console.log(zs);
console.log(ls);
输出结果:
6、自定义构造函数
function Person(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
}
var obj1 = new Person("张三",12,"男");
var obj1 = new Person("李四",13,"女");
var obj1 = new Person("王五",11,"女");
这时候,我们会奇怪,因为函数并没有被对象调用,那this指的是谁?函数并没有返回值,得到的是什么?
构造函数和普通函数不同的地方在于使用new的时候,中间发生了很多看不见的过程:
- 创建了一个新对象
- this指向了这个新对象
- 执行构造函数中的代码,给对象添加属性和方法
- 返回这个新对象
使用new构造函数来创建对象的过程称之为实例化
构造函数注意事项:
- 构造函数天生就是用来创建对象的,所以必须和new配合使用,否则就不具备创建对象的能力
- 构造函数内部不能有return关键字,因为构造函数会自动返回对象。如果返回基本数据类型,和不加效果一样,如果返回复杂数据类型,构造函数就没意义了。
- 如果new的时候,不需要参数,那么小括号可以省略
- 人们通常将构造函数的首字母大写
此时的构造函数有个缺点:
从一个构造函数中创建出的对象,实现的是同一种功能,他们拥有的方法应该是一样的,也就是说,同一个构造函数中new实例化得到对象,应该具备同样的方法。
例:
function Person(name){
this.name = name;
this.say=function(){
console.log("说话");
}
}
var obj1 = new Person("张三");
var obj2 = new Person("李四");
console.log(obj1.say == obj2.say); // false 表示这是两个空间
通过比较发现,方法是不一样的。造成了内存浪费。
// 自定义构造函数
// function fn() {}
// let f = new fn()
// console.log(f);
// function person() {}
// let p = new person()
// console.log(p);
// 可以使用自定义构造函数解决工厂函数的缺点
// 自定义构造函数的时候有几个注意事项:
/*
1.约定成俗 构造函数的首字母通常都是大写的
2.在new他的时候,如果不需要传递参数,就可以省略小括号
3.构造函数也是函数,也能当做普通函数去调用它
*/
// function Person(){}
// let p1 = new Person()
// console.log(p1);
// let p2 = new Person
// console.log(p2);
// function Man() {
// console.log(666);
// }
// let m = new Man
// console.log(m);
// Man()
总结:
1.new操作符到底干了什么?
2.this在构造函数中代表new出来的对象
全局
普通函数
事件函数
自调用函数
定时器函数
对象方法
箭头函数
7、原型
7.1、原型概念
任何一个对象提升自带一个属性:__proto__,这个属性对应的值是一个对象,这个对象叫做对象的原型,或叫做对象的原型对象。
var obj = {}
console.log(obj)
效果:
7.2、原型作用
原型中的属性和方法,默认就能被对象所访问。
var arr = []
console.log(arr)
图示:
关系介绍
<script>
function Person(name) {
this.name = name
}
let p1 = new Person('p1')
let p2 = new Person('p2')
console.log(p1, p2);
// 测试p1和p2是否拥有同一个原型
// console.log( p1.__proto__ === p2.__proto__ ); // true
// 构造函数比作 母
// new出来的对象比作 子
// 原型比作 父
// 构造函数和原型之间的关系
console.dir(Person)
// 比较构造函数的prototype和原型是否是同一个
console.log( p1.__proto__ === Person.prototype ) // true
// 函数会天生自带属性prototype,指的是原型
// 原型天生自带属性constructor,指的是构造函数
</script>
效果:
面向对象写tab切换
面向对象书写步骤:
1.定义空构造函数 - 定义对象,调用方法实现效果,调用方法,就需要给原型上添加对应的方法
2.new构造函数的时候需要添加参数 - 通常是效果中最大标签选择器 - 添加形参
3.在构造函数中将所有需要操作的标签作为对象的属性
4.将事件放在init方法中