1 /*
2 面向对象的三个概念
3 1、类:是一个抽象概念,是产生对象的一个容器
4 2、对象(实例):是一个实体,由类产生出来的一个带有类属性和方法的实体。
5 3、实例化:产生对象的过程
6 */
7
8
9 //一、 构造函数:是一个特殊的函数,用来模拟类,是产生对象的模板
10 // 1、构造函数内部使用了this关键词,this表示要产生对象的实体
11 // 2、必须要用new关键字实例化
12 function ClassPeople (name,age) {
13 this.name = name;
14 this.age = age;
15 console.log(this);//person person2
16 }
17 var person = new ClassPeople('ls', 18)//这里this就指向这个对象
18 console.log(person);//ClassPeople {name: "ls", age: 18}
19 var person2 = new ClassPeople('zs', 19)//这里this就指向这个对象
20 console.log(person2);//ClassPeople {name: "zs", age: 19}
21
22 //非严格模式下,函数的this指的是window全局对象,有了new命令后,指向的是对象
23
24 //3、new.target 如果当前函数是new命令调用,new.target指向的是当前函数,否则是undefined
25 function ClassAnimal(name, age) {
26 this.name = name
27 this.age=age
28 console.log(this);//ClassAnimal {name: "ls", age: 18}
29 console.log(new.target);//此函数
30 }
31 var animal = new ClassAnimal('ls', 18)//new命令调用
32
33
34
35
36
37
38 //二、object.create(proto,[propertiesObject]),可以把对象作为一个模板,生成新的实例对象
39 var cat = {
40 name: 'cat',
41 age:10
42 }
43 var cat1 = Object.create(cat, { go: { value: 'go' } })
44 console.log(cat1);//{go: "go"}
45
46
47
48
49
50
51 // 三、this除了用在构造函数里面,还可以用在其他场合。
52 // 1. this返回的总是一个对象。
53 // 2. this代表就近调用该属性或者方法的对象
54
55 var persona = {
56 name: 'zs',
57 move: function () {
58 console.log(this);
59 return this.name;
60 }
61 }
62 var personb = {
63 name:'ls'
64 }
65 personb.move = persona.move;
66 var res = personb.move();//personb对象
67 console.log(res);//ls
68
69
70
71
72
73
74 //四、绑定this,this默认是动态切换的,有时候需要把this固定下来
75 //1.call(object,arguments),可以改变函数内部的this指向object,arguments为函数的其他参数
76 var obj = { name: 'test' }
77 function f1(a,b) {
78 console.log(this, a, b);
79 }
80
81 f1.call(obj, 123, '12')//f1函数内部的this指向obj对象,如果obj是null或者undefined,则不能改变this的指向。{name: "test"} 123 "12"
82 f1()
83 //2.apply(object,[argument]),和call一样,只是传递的参数需要放到数组里面传递
84 f1.apply({ name: 'dl', age: 18 }, [123, '12'])//{name: "dl", age: 18} 123 "12"
85 //3.bind()将函数体内的this绑定到某个对象,返回一个新的函数
86 var counter = {
87 count: 0,
88 inc: function(){
89 console.log(this);
90 this.count++;
91 }
92 }
93 var counter2 = {
94 count: 2,
95 }
96 var func = counter.inc.bind(counter2)//j将this指向counter2
97 func()//{count: 2}
98 console.log(counter2.count);//3
99
100
101
102
103
104
105 // 五、对象的继承
106 // 面向对象编程很重要的一个特征就是有继承概念。A对象继承B对象,A对象就有了B对象的所有属性和方法。
107 // 大部分面向对象编程语言都是通过类实现继承,js没有类的体现,只能通过改变this指向的方式实现继承。
108 function Animals(name,age){
109 this.name = name,
110 this.age = age,
111 this.mouse = function () {
112 console.log('mouse');
113 }
114 }
115 function Cat() {
116 Animals.call(this,'lyb','18')
117 this.color = 'red',
118 this.move = function () {
119 console.log('move');
120 }
121 }
122 var cat = new Cat()
123 console.log(cat);//Cat {name: "lyb", age: "18", mouse: ƒ, color: "red", move: ƒ}
124
125
126
127
128
129 // 六、原型对象
130 // 1. 原型就是一个共享对象。每个函数都有一个prototype属性,指向一个对象(就是一个原型对象),把属性和方法都定义到原型上,就可以实现多个对象的属性和方法的共享,节省了内存。
131 function People(name){
132 this.name = name;
133 // this.say = function () {
134 // console.log('i say');
135 // }
136 }
137 People.prototype.say = function () {// 把公有的say方法放在People方法的原型对象上面,构造函数产生的对象会自动有该原型。
138 console.log('i say');
139 }
140 console.log(People.prototype);//{say: ƒ, constructor: ƒ}
141 var pe1 = new People('zs')
142 var pe2 = new People('ls')
143 console.log(pe1, pe2);////People {name: "zs"} People {name: "ls"}
144 pe1.say();//i say
145 // 2. 原型链: 所有的对象都有一个原型对象,可能原型对象还有自己的原型对象,这样一直可以找下去,null没有任何属性和方法,原型链的尽头就是null。
146 console.log({ name: "1111" });
147
148
149
150
151
152
153 //七、原型对象的继承
154 function Father() {
155 this.name='p1'
156 }
157 Father.prototype.move = function () {//父类原型对象中添加move方法
158 console.log('move');
159 }
160
161 function Son() {// Son类对象(son1)的原型对象(__proto__:)中默认有一个constructor属性,该属性就是该构造函数
162 // 本体属性: 构造函数this上的属性。
163 // 如果在原型中(__proto__:),则是原型对象属性。
164 // 获取对象的属性是先找本体属性,没有找到再去原型对象中找,直到所有原型对象都没有找到,就返回undefined。
165 //Father.call(this) 不能继承父类的原型对象属性,只能继承父类中的本体属性(this)
166 //如果要实现原型对象继承,需要采用赋值的方法Son.prototype.move = Father.prototype.move;
167 //构造函数中的原型对象会继承到创建的对象中(son1会自动拥有Son的原型对象prototype属性)
168 Father.call(this)//
169 this.age=18
170 }
171 //继承原型对象属性
172 Son.prototype.move = Father.prototype.move;
173 var son1 = new Son()
174 console.log(son1);//如下
175 /*
176 Son {name: "p1", age: 18}
177 age: 18
178 name: "p1"
179 __proto__://原型对象
180 move: ƒ ()//move方法 实现了继承
181 constructor: ƒ Son()//创建此函数的构造函数
182 __proto__: Object
183 */
184
185
186
187
188
189
190 //八、instanceof运算符 返回一个bool值,表示对象是否为某个构造函数的实例
191 var arr = [1, 2, 3];
192 console.log(arr instanceof Array);//true
193 console.log(son1 instanceof Father);//false
194 console.log(son1 instanceof Son);//true
195
196
197
198
199 // 九、 Object.getPrototypeOf(obj)返回参数对象的原型对象,是获取原型对象的标准方法
200 console.log(Object.getPrototypeOf(son1));
201 /*
202 {move: ƒ, constructor: ƒ}
203 move: ƒ ()
204 constructor: ƒ Son()
205 __proto__: Object
206 */
207
208
209 //十.Object.setPrototypeOf(obj_a obj_b)设置参数对象的原型对象 把a对象的原型对象设置为b
210 var a = {name: "a"};
211 var b = { age: 123 };
212 Object.setPrototypeOf(a, b)
213 console.log(a);
214 /*
215 {name: "a"}
216 name: "a"
217 __proto__:
218 age: 123
219 __proto__: Object
220 */
221
222
223
224
225
226
227
228
229
230 // 十一、isPrototypeOf(obj) ,用于判断一个对象是否为参数对象的原型.
231 var a = {name: "a"};
232 var c = Object.create(a);
233 console.log(a.isPrototypeOf(c)); // 判断a对象是否为c对象的原型//true
234
235
236
237
238
239 // 十二、 Object.create(a,b); // 返回一个以a为原型对象的新对象,{}创建本体属性。
240 var c = Object.create(a,{test:{value:"cccc"}});
241 console.log(c);
242
243
244
245
246
247
248 // 十三、 __proto__,返回对象的原型
249 console.log(c.__proto__);
250 /*
251 {name: "a"}
252 name: "a"
253 __proto__: Object
254 */
255
256
257
258
259 // 十四、 hasOwnProperty() 用于判断属性是在对象自身(true)还是原型中
260 console.log(a.hasOwnProperty("name"));//true
261
262
263
264
265
266
267
268
269 // 十五、js的严格模式
270 // 一般js编程是用的正常模式,除了正常模式还有一种严格模式,严格模式就是才用更严格的js语法。严格模式是从ES5引入的标准,让js更严谨,为js以后的升级做过渡。
271 // 1. 在js脚本开头添加"use strict",表示整个js脚本都开启严格模式。
272 // 2. 严格模式下,变量必须显示声明。
273 // 3. 不能删除一个变量或函数
274 // 4. 严格模式下函数内部没有this,this是undefined,正常模式下this指向的是window
275 function test() {
276 "use strict"; // 要么放在文件开头,也可以放在函数里面,表示函数内部开启严格模式
277 var sex = "a1";
278 var person1 = {};
279 // delete person1;
280 // function f1(a,a,){
281 // console.log(a)
282 // }
283 function p1(){
284 console.log(this);
285 }
286 p1();
287 }
288
289
290 test();