JavaScript的面向对象是基于constructor(构造函数)与prototype(原型链)的。
构造函数:constructor
构造函数就是一个函数。和普通函数有一些区别。
constructor: 构造器。指向自己的构造函数。
区别:
1.函数的内部使用this的关键字。
2.首字母是大写的。
3.使用的时候要用new操作符创建实例对象。
原型:prototype
原型是一个对象,称为原型对象。
构造函数创建实例对象,构造函数具有原型
实例对象也具有原型。实例对象的原型指向构造函数的原型。这就是原型链。
__proto__:每一个实例对象都具有的私有属性。指向自己的原型。
new 创建对象实例
防止漏掉new造成错误:
- 在构造函数内部使用严格模式。
- 使用instanceof在内部判断。判断是否为当前对象的实例。
- 使用new.target 在内部判断,new.target指向自己的构造函数。
eg:
<script type="text/javascript">
//在构造函数内部使用严格模式
function A(name){
'use strict';
this.name = name;
}
let a = new A('lisi');
//使用instanceof在内部判断,判断是否为当前对象的实例
function B(name){
//this 指向新创建的实例
if(!(this instanceof B)){
return new B(name);
}
this.name = name;
}
let b = new B('lisi');
console.log(b.name);
let bb = B('sisi');
console.log(bb.name);
//使用new.target在内部判断,new.target指向自己的构造函数
function V(name){
if(!(new.target == V)){
throw new Error('这个对象必须使用new来创建新对象')
}
this.name = name;
}
let v = new V('ll');
let vv = v('ll');//当不使用new的时候就会报错
</script>
new的深入操作
1.创建一个空对象,作为将要返回的对象实例。
2.将这个空对象的原型,指向构造函数的prototype属性。
3.将这个空对象赋值给函数内部的this关键字。
4.开始执行构造函数内部的代码。
5.将对象实例返回
构造函数里面的return语句
1.如果return的是普通数据类型。那么相当于没写。
2.如果返回的是this,那么返回的与本身返回的是一样的。
3.如果返回的是一个其他对象。那么结果返回的就是这个对象。
所以在构造函数内部返回对象要小心。
eg:
<script type="text/javascript">
//如果return是普通数据类型,那么相当于没写
function A(name){
this.name = name;
return 123;//简单数据类型
}
let a = new A('12');
console.log(a);
//如果返回的是this,那么返回的与本身返回的是一样的
function B(name){
this.name = name;
return this;
}
let b = new B('12');
console.log(b);
//如果返回的是一个其他对象,那么结果返回的就是这个对象,所以在构造函数内部返回对象要小心
function C(name){
this.name = name;
return {
name:'liso'
};
}
let c = new C('12');
console.log(c);//object
</script>
任何一个函数都可以使用new。返回值都是一个对象。
如果这个函数是一个构造函数的话,返回的是这个函数的实例。
如果函数是一个普通函数,那么返回的是一个空的对象。
eg:
<script>
console.log(Object.prototype.__proto__);
//Object的原型指向null,一切对象的基础是null,null也叫空。
//Object对象是所有JS对象的基础
</script>
![](https://img.haomeiwen.com/i14033677/f3a8c0ff7835944c.jpg)
Object.create();
有的时候我们拿不到对象的构造函数。可以根据这个对象的某一个实例去创建一个对象。
对于对象来说,每一个属性 其实都有四个描述。
value 值
enumerable 枚举 遍历 for in
configurable 修改
writable 删除
后面三个默认值都是true。
eg:
<script>
function A(name){
this.name = name;
}
let a = new A('lisi');
let b = Object.create(a);
//有时候我们拿不到对象的构造函数,可以根据这个对象(Object.create())的某一个实例去创建一个对象
console.log(b);
b.name = 'zhangsan';
console.log(a.name);
</script>
<script type="text/javascript">
let obj = new Object();
//添加属性
obj.p1 = 'zhangsan';
obj.p2 = 18;
let obj2 = Object.create(obj,{//修改属性的值
//对于对象来说每一个属性其实都有四个描述
//value(值)、enumerable(枚举 遍历)、configurable(修改)、writable(删除)后面三个描述默认值为true
p1:{
value:'lisi',
enumerable:false,
},
p2:{
value:19,
enumerable:true,
configurable:true,
writable:true,
}
});
console.log(obj2);
//遍历
for(let i in obj2){
console.log(i,obj2[i]);
}
</script>
<script type="text/javascript">
var obj = {
a:'a',
b:'b',
c:'c',
};
for(let i in obj){
console.log(i,obj[i]);
}
console.log('------------');
//当enumerable的值为false时它对应的值就不会显示了
Object.defineProperty(obj,'c',{
//Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。
value:13,
enumerable:false,
});
for(let i in obj){
console.log(i,obj[i]);
}
</script>
![](https://img.haomeiwen.com/i14033677/93b606b6c5e523c8.jpg)
![](https://img.haomeiwen.com/i14033677/2d5bdb3906a55742.jpg)
![](https://img.haomeiwen.com/i14033677/8289e849770e24c9.jpg)
Object.getPrototypeOf(obj)
<script type="text/javascript">
function A(name){
this.name = name;
}
let a = new A('zhangsan');
console.log(Object.getPrototypeOf(a));//获取实例对象的原型
console.log(a.__proto__);
Object.getPrototypeOf({}) === Object.prototype;//ture
//new Object 与 Object 的原型是一致的,对象的原型与构造函数是一致的。
Object.getPrototypeOf(Object.prototype) === null
//Object对象的原型的原型指向null,null也是原型链的顶点
function f(){
Object.getPrototypeOf(f) === Function.prototype //true
//构造函数的原型与内置对想function的原型相同 f === new Function();
}
</script>
Object.setPrototypeOf(obj)
<script type="text/javascript">
let a = new Array();
console.log(Object.getPrototypeOf(a));
Object.setPrototypeOf(a,Number.prototype);
//setPrototypeOf()设置一个指定对象的原型到另外一个对象或null;
console.log(Object.getPrototypeOf(a));
</script>
isPrototypeOf()
<script type="text/javascript">
let a = new Array();
let b = new Array();
console.log(Array.prototype.isPrototypeOf(b));//true
let c = Array.prototype;
console.log(c.isPrototypeOf(b));//true
//判断该对象是否为参数对象的原型
</script>
Object.prototype.hasOwnProperty()
Object.getOwnPropertyNames()
<script type="text/javascript">
function A(name){
this.name = name;
this.say = function(){
console.log(a);
}
}
A.prototype.ss = function(){
console.log('ss');
}
function B(name){
A.call(this);//继承
this.age = 16,
this.sex = 'man'
};
for(let i in A.prototype){
B.prototype[i] = A.prototype[i];
}
console.log(Object.prototype);
let b = new B('lala');
b.ss();
console.log(Object.getOwnPropertyNames(b));
//getOwnPropertyNames成员是参数对象本身的所有属性的键名,不包含继承的属性键名
console.log(B.prototype.hasOwnProperty('say'));//false
//prototype.hasOwnProperty用于判断某个属性定义在对象本身还是定义在原型链上
网友评论