一、对象的举例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>对象的举例</title>
</head>
<body></body>
</html>
<script type="text/javascript">
/*
面向对象:就是一种编程思想,是由属性和方法组成的
面向对象的方法:封装、继承、多态
面向对象的特点:
抽象:把主要特征和问题相关的特征抽离出来
封装:看不到里面的对象,用好表面的功能
继承:遗传,从父类继承出一些方法和属性,子类又有自己独特的特征
*/
// js对象都是由属性和方法组成的,变量就是属性,函数就是方法
var a = 12; // 变量是自由的 不属于任何人
var arr = [11, 22, 33];
arr.a = 12; // 设置属性
console.log(arr);
// 变量能做的事,属性也能做,属性和变量其实是一个东西,只不过变量是自由的,属性是属于一个对象的。
// 函数就是方法
var obj = {};
obj.name = "张三";
obj.age = "18";
obj.getName = function () {
console.log(this.name);
};
obj.getName();
console.log(obj);
/*
等价于
var obj = {
name:'张三',
age:'18',
getNmae: function(){
console.log(this.name)
}
}
*/
</script>
二、封装函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>封装函数</title>
</head>
<body></body>
</html>
<script type="text/javascript">
var obj = {};
// 设置属性
obj.name = "name";
obj.age = "age";
// 设置方法
obj.getName = function () {
console.log("我的名字是" + this.name);
};
obj.getAge = function () {
console.log("我的年龄是" + this.age);
};
/*
等价于:
var obj = {
name:'name',
age:'age',
getName:function(){
console.log('我的名字是'+this.name)
},
getAge = function(){
console.log('我的年龄是'+this.age)
}
*/
console.log(obj);
obj.getName();
obj.getAge();
// 上述方法的缺点:当我们创建多个对象的时候,重复代码太多了
// 要进行封装,所以就有了工厂模式
</script>
三、工厂模式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>工厂模式</title>
</head>
<body></body>
</html>
<script type="text/javascript">
// 工厂模式就是创建对象的一种方式(原料--加工--出厂)
function createFn(name, age) {
// 1.创建空白对象
var obj = new Object(); // var obj = {}
// 2.加工原材料(添加属性和方法)
obj.name = name;
obj.age = age;
obj.getName = function () {
console.log("我的名字是" + this.name);
};
obj.getAge = function () {
console.log("我的年龄是" + this.age);
};
// 3.出厂
return obj;
}
var obj1 = createFn("张三", 18);
var obj2 = createFn("李四", 20);
console.log(obj1, obj2);
obj1.getName();
obj2.getAge();
// 如果创建了不同的对象 其中的属性方法会重新建立 消耗内存 所以 出现了构造函数
</script>
四、构造函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>构造函数</title>
</head>
<body></body>
</html>
<script type="text/javascript">
/*
什么是构造函数:
在js中用new关键字来调用的函数被称为构造函数 new Array new Date ...
new 在执行时会做四件事:
1.在内存中创建一个新的空对象
2.让this指向这个空对象
3.执行构造函数里面的代码,给这个新对象添加属性和方法
4.返回这个空对象(构造函数里面不需要return)
*/
function createFN(name, age) {
// 省去了创建空对象这一步
// 让this指向这个空对象
this.name = name;
this.age = age;
this.getName = function () {
console.log("我的名字是" + this.name);
};
this.getAge = function () {
console.log("我的年龄是" + this.age);
};
}
var obj1 = new createFN("张三", 18);
obj1.getName(); // 我的名字是张三
var obj2 = new createFN("李四", 20);
console.log(obj1, obj2);
console.log(obj1.getName == obj2.getName); // false
// 这两个对象有相同的功能,在不能说共用了一个方法,每new一次,系统会创建一个内存,两个对象各自执行各自的,这样会消耗内存
// 如果想让两个对象共用一个方法怎么办?--原型
/*
构造函数和工厂模式相比,省去了创建空对象和将结果返回出去这两个步骤
什么是构造函数?构造函数偷偷帮我们干了哪两件事?
在js中,用new关键字调用的函数称为构造函数
1.帮我们偷偷创建了一个空白对象
2.替我们将结果返回出去
*/
</script>
五、原型
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>原型</title>
</head>
<body></body>
</html>
<script type="text/javascript">
/*
什么是原型?
在js中,每个对象都有一个原型(prototype),原型是一个对象,它包含共享的属性和方法 可以被其他对象继承和访问。对象可以通过原型继承属性和方法,而不是通过复制。
什么是原型链?
js中的原型链是一种通过原型链接起来的对象层级结构。每个对象都有_proto_这个属性,这个属性指向它的原型对象。原型对象也是对象,也有_proto_这个属性,指向原型对象的原型对象,这样一层一层的形成链式结构,称为原型链。当我们访问一个对象的属性和方法时,如果对象本身没有这个属性和方法,js引擎会沿着原型链向上查找。知道找到该属性或方法或者达到原型链顶部为止,如果顶层也找不到,返回null。
*/
function createFN(name, age) {
this.name = name;
this.age = age;
// 添加原型的方法
// 将getName这个方法添加到对象的原型上
createFN.prototype.getName = function () {
console.log("我的名字是" + this.name);
};
createFN.prototype.getAge = function () {
console.log("我的年龄是" + this.age);
};
}
var obj1 = new createFN("张三", 18);
var obj2 = new createFN("李四", 20);
console.log(obj1, obj2);
console.log(obj1.getName == obj2.getName); // true
</script>
六、原型求和
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>原型求和</title>
</head>
<body></body>
</html>
<script type="text/javascript">
var arr1 = [11, 22, 55, 66, 99, 100];
var arr2 = [55, 2, 16, 95, 55];
// 将sum方法添加到了Array的原型上
Array.prototype.sum = function () {
var result = 0;
// this关键字指向的是调用方法的数组对象
for (var i = 0; i < this.length; i++) {
result += this[i];
}
return result;
};
console.log(arr1, arr2);
console.log(arr1.sum());
console.log(arr2.sum());
</script>
七、call&bind&apply
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>call&bind&apply</title>
</head>
<body></body>
</html>
<script type="text/javascript">
var bd = {
name: "百度",
say: function (val) {
console.log(this.name, val);
},
};
var tx = {
name: "腾讯",
say: function (val) {
console.log(this.name, val);
},
};
bd.say("李彦宏"); //百度 李彦宏
tx.say("马化腾"); //腾讯 马化腾
// 对象.属性.call('让this指向那个对象','传递的参数')
// 在调用bd中的say方法时,让bd这个对象中的this执向tx这个对象
bd.say.call(tx, "李彦宏"); // 腾讯 李彦宏
// 对象.属性.apply('想让this指向的那个对象',['传递的参数'])
bd.say("张三");
bd.say.apply(tx, ["张三"]); // 腾讯 张三
// bind 返回的结果是个函数
var result = tx.say.bind(bd, "name");
result(); // 百度 name
/*
call、apply、bind总结:
相同点:call apply bind都可以改变this的指向
不同点:
1.call和apply会调用函数,而bind返回的是一个新的函数
2.传参不一样,apply传的参数是数组的形式
请说一下你对this的理解?
在浏览器中,全局范围内this指向的是window
在普通函数中,this指向的是当前函数的调用者
在构造函数中,this指向的是new出来的那个新对象
call、apply、bind中的this指向的是强制绑定的那个对象
*/
</script>
八、继承
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>继承</title>
</head>
<body></body>
</html>
<script type="text/javascript">
function Animal() {
this.category = "动物";
}
function Cat(name, color) {
this.name = name;
this.color = color;
}
// 怎么样能使猫继承动物中的category属性
// 方法1 在Cat构造函数中 调用Animal这个构造函数 并且修改Animal的this指向 让它指向cat
/*function Car(name,color){
Animal.call(this)
this.name = name
this.color = color
}
var xm = new Cat('miqi','黑色')
console.log(xm)*/
// 方法2
// constructor是js中的一个特殊属性,存在于每个对象的原型上,当创建一个对象时,js会自动为该对象添加一个constructor属性,指向用于创建该对象的构造函数
// 将猫的原型指向一个动物的构造函数
Cat.prototype = new Animal();
/*
Cat.prototype = new Animal() 将Cat.prototype设置为了Animal实例,这样会导致Cat.prototype.constructor指向Animal构造函数而不是Cat,为了确保Cat.prototype.constructor指向其正确的构造函数,即Cat构造函数,需要显示得将其设置为Cat
*/
Cat.prototype.constructor = Cat;
var zgc = new Cat("miqi", "黑色");
console.log(zgc);
</script>
九、笔记
什么是面向对象?
面向对象就是一种编程思想,是由属性和方法组成的。
面向对象的特点:
抽象:把主要特征和问题相关的特征抽离出来
封装:看不到里面的对象,用好表面的功能
继承:遗传,从父类继承出一些方法和属性,子类又有自己独特的特征
工厂模式
1.原材料
2.加工 (添加属性和方法)
3.出厂 (return obj)
原型:每个对象都有原型属性,我们把方法写在原型上,这样我们创建出来的对象就可以共用原型上的方法
什么是构造函数?
在js中,用new关键字来调用的函数称为构造函数
继承方法:
1.call/apply
2.原型链继承
2.利用空对象作为中介