一、对象创建方式(3种)
<body>
<!--
创建对象
-->
<script>
// 1.字面量
var obj = {
name:'王多磊',
age:20,
sex:'woman',
study:function(){
console.log('我爱学习')
}
}
console.log(obj.sex)
obj.study()
// 2.new关键字
var obj = new Object({
name:'王多磊',
age:20,
sex:'woman'
})
console.log(obj.sex)
// 3.构造函数 如果出现大量相同的属性和方法时,可以使用构造函数
function Person(name,age){
this.name=name
this.age=age
this.study=function(){
console.log('我爱学习')
}
}
var wdl = new Person('王多磊',20)
var ply = new Person('潘露阳',30)
console.log(wdl.name);
console.log(ply.age);
ply.study()
</script>
</body>
二、构造函数特点
<body>
<script>
/*
构造函数:主要用来创建对象,也叫实例化对象
场景:创建多个属性或相同的对象时使用
特点:命名需要大写,用new关键字执行
使用new调用函数的过程叫实例化(创建对象)
构造函数不需要return就可以返回创建的对象(对return不起作用)
new出来的对象都是独立存在的
每次new构造函数时,就会在内存空间中新储存一个相同的方法,所以构造函数用多了会浪费内存空间
*/
function Person(name,age){
this.name=name
this.age=age
this.study=function(){
console.log('我爱敲代码');
}
}
var wdl = new Person('王多磊',20)
var ply = new Person('潘露阳',22)
console.log(wdl);
console.log(ply);
wdl.study()
function person(name,age){
this.name=name
this.age=age
this.study=function(){
console.log('我爱敲代码');
}
}
var wdl = new person('王多磊',20)
var ply = new person('潘露阳',22)
console.log(wdl);
console.log(ply);
wdl.study()
</script>
</body>
三、构造函数中new的作用
<body>
<script>
/*
new具体干了什么:
1.创建空对象
2.this指向创建的这个对象
3.通过this把属性和方法添加到这个对象上
4.返回这个对象(类似于return)
构造函数中的this指向这个对象
this指向这个创建的对象,name以及age通过形参的方式传进来存到这个对象的name和age身上
*/
function Person(name,age){
this.name=name
this.age=age
console.log(this);
this.study=function(){
console.log(this);
console.log('我爱敲代码');
}
}
var wdl = new Person('王多磊',20)
wdl.study()
</script>
</body>
四、静态和实例成员
<body>
<script>
/*
实例化对象中属性(实例属性)和方法(实例方法)就叫做实例成员
实例成员就是构造函数内部通过this添加的成员,就像name和age就是实例成员
静态成员:在构造函数本身(Person)上添加的成员,想访问静态成员的话,需要通过构造函数进行访问
*/
function Person(name,age){
this.name=name
this.age=age
console.log(this);
this.study=function(){
// console.log(this);
console.log('我爱敲代码');
}
}
Person.eye='two'
var wdl = new Person('王多磊',20)
var zsl = new Person('张士龙',23)
// 实例成员只能通过实例化对象(wdl)进行访问
console.log(wdl.name);
console.log(wdl.age);
// console.log(Person.name);//访问不到
console.log(wdl.eye);//undefined
// wdl.study()
console.log(zsl);
// 静态成员需要通过构造函数进行访问
console.log(Person.eye);//two
</script>
</body>
五、原型对象
<body>
<script>
/*
prototype属性:所有对象都可以使用存在构造函数中prototype属性里的方法
js规定,每一个构造函数都有一个prototype属性(只要创建了构造函数就会自动有prototype属性)。
prototype属性也称为对象,存在prototype里面的方法和属性都属于这个构造函数
场景:可以把相同的方法,直接写在prototype对象上,这样所有创建出来的对象都可以使用到
构造函数是通过原型分配的函数,也就是说prototype也叫原型对象
prototype中的方法 this也指向创建的对象
*/
function Person(name,age){
this.name=name
this.age=age
// this.study=function(){
// console.log('我爱敲代码');
// console.log(this)
// }
}
Person.prototype.study=function(){
console.log('我爱敲代码');
console.log(this) //person
}
var wdl = new Person('王多磊',20)
var zsl = new Person('张士龙',23)
console.log(wdl.study===zsl.study);//false true
console.log(wdl===zsl);//false false
// console.dir(Person.prototype);//对象
wdl.study()
wdl.__proto__.study()
Person.prototype.study()
// console.log(wdl.study());
</script>
六、对象原型
<body>
<script>
/*
__proto__:对象原型:只要构造函数在prototype里存储方法或属性时,
创建的对象都可以通过对象上的__proto__这个属性访问到
也就是说__proto__是对象上的属性
在现在的浏览器上显示的是[[prototype]],他就代表是__proto__
以前的浏览器显示的是__proto__,但__proto__是非标准的写法
*/
function Person(name,age){
this.name=name
this.age=age
// this.study=function(){
// console.log('我爱敲代码');
// console.log(this)
// }
}
Person.prototype.study=function(){
console.log('我爱敲代码');
}
var wdl = new Person('王多磊',20)
console.log(wdl.__proto__===Person.prototype);//true 他们两个指向的同一个地方
console.log(wdl.__proto__);
console.log(Person.prototype);
</script>
</body>
7.constructor构造函数
<body>
<script>
/*
constructor 构造函数
对象原型(__proto__)和原型对象(prototype)他们都有一个constructor属性,constructor属性也叫构造函数
而且他指向构造函数本身(Person)
场景:用于查找该对象引用的是哪个构造函数
*/
function Person(name,age){
this.name=name
this.age=age
}
// 直接给原型对象上添加方法时不会出现找不到constructor构造函数(能指回原来的构造函数)
// Person.prototype.study=function(){
// console.log('我爱敲代码');
// }
// 如果有多个对象方法,可以采用给原型对象赋值的方式,但会覆盖原来的原型对象的内容,就会出现constructor不再指向原来的构造函数,我们需要通过添加constructor指向原来的构造函数
Person.prototype={//这种写法改变了prototype的构造函数指向,因为是直接给prototype赋值了一个对象
constructor:Person,//手动指回原来的构造函数
study:function(){
console.log('我要学习');
},
speak:function(){
console.log('我要说话');
}
}
var wdl = new Person('王多磊',20)
// console.log(wdl.__proto__);
// console.log(Person.prototype);
console.log(wdl.__proto__.constructor);
console.log(Person.prototype.constructor);
</script>
</body>
8.原型链
<body>
<script>
/*
所有的对象上都有原型对象(prototype),所有的原型对象上都有对象原型(__proto__),那种查找方式就是原型链
(一级一级朝上查找)
其实构造函数就是在创建对象,构造函数的终极Boss就是Object
如果Object身上都没有想要找的方法,那就回返回null
*/
function Person(name,age){
this.name=name
this.age=age
// this.study=function(){
// console.log('我爱敲代码');
// console.log(this)
// }
}
Person.prototype.study=function(){
console.log('我爱敲代码');
}
var wdl = new Person('王多磊',20)
console.log(Person.prototype.__proto__);//Object
// console.log(Object.prototype);
console.log(wdl.__proto__.__proto__.__proto__);//null
console.log(Person.prototype);//Object
</script>
</body>
9.this指向问题
<body>
<script>
/*
构造函数的this指向实例化对象
如果想要拿到方法中的this需要先调用,构造函数中方法中的this指向实例化对象
原型对象上的方法中this指向实例化对象
如果构造函数内和原型对象上有相同的方法时,会执行构造函数上的,原因是就近原则
*/
var that
function Person(name,age){
this.name=name
this.age=age
// this.study=function(){
// console.log('我爱敲代码');
// }
}
Person.prototype.study=function(){
console.log('我爱敲代码11111')
that=this
}
var wdl = new Person('王多磊',20)
wdl.study()
console.log(wdl===that)
</script>
</body>