现实生活中的对象:是指某一个具体的事物
生活中具体的事物,都是有特征和行为能够描述这个对象
面向对象编程其实也是将现实生活中的事物,抽象到编程代码中:
现实中的事物对象----抽象--->代码中对象
特征----------->属性
行为----------->方法
创建对象
// 1. 字面量创建对象
let objStu = {
name: 'chuanguo',
age:18,
like:()=>console.log('code')
}
// 2. 内置构造函数创建对象
let stu1 = new Object();
// js动态语言,对象没有这个属性,直接动态添加
stu1.name = 'luoda';
stu1.age = 18;
stu1['like'] = ()=>console.log('洗脚');
let variable = 'grender';
stu1[variable] = '男';
console.log(stu1);
内置构造函数创建对象
let stu1 = new Object();
stu1.name = 'luoda';
stu1.age = 18;
// 工厂函数创建
// 通过函数创建对象
function createObj(name,age){
// 通过内置构造函数创建对象
let obj = new Object();
// 给对象动态添加属性
obj.name = name;
obj.age = age;
// 将创建的对象返回
return obj;
}
let obj1 = createObj('luoda',18);
let obj2 = createObj('chuanguo',18);
let obj3 = createObj('lisi',18);
自定义构造函数
1. 函数名首字母(大写)
2. 使用方式,构造函数就是用创建对象,通过关键字 new 构造函数
3. 在构造函数的this关键字,指向创建的实例对象
4. 不需要写return, 构造函数会自动的将this中的实例对象返回
也可以写return,但是如果return的基本数据类型则不影响创建的结果
但是如果return的引用数据类型,则会影响创建的结果
构造函数是用来创建对象:
通过new 构造函数创建对象,创建的对象我们也叫实例对象
通过new 构造函数创建对象的过程中,构造函数做了哪些事?
1. 在内存中开辟了一个对象空间(就是创建的实例对象)
2. 将关键字this指向了这个空间
3. 执行构造函数中的代码(给这个空间中添加数据,也就是给实例对象添加属性和方法)
4. 将this指向的实例对象返回
// 通过自定义的构造函数创建对象
构造函数实例化对象,实例对象
let mi = new Phone('小米11','mi','6.7','土豪金',4000);
console.log(mi);
调用实例对象的方法
mi.call();
获取实例对象的属性值
console.log(mi.price);
console.log(mi['price']);
实力对象属性的修改
mi.price = 2000;
console.log(mi);
// 所有的函数中有一个属性prototype,这个属性指向的是一个对象空间
构造函数也是函数,也有prototype属性,构造函数的prototype属性指向的也是一个对象空间
对象空间中都可存储数据,所以构造函数的prototype属性指向的对象空间也可以存储数据
// 构造器
console.log(per1.__proto__.constructor === Person); // true
console.log(Person.prototype.constructor === Person); //true
将方法写到构造函数中,会造成内存的浪费
console.log(per1.sayHi == per2.sayHi); // true
console.log(per1.__proto__ === Person.prototype); // true
函数都有一个prototype属性,指向的构造函数的原型对象,
prototype这是一个标准属性,是给程序员使用的
对象都有一个__proto__属性,指向创建这个对象的构造函数的原型对象
__proto__是一个非标准属性,是给浏览器使用的
对象访问属性或方法,现在自己身上找是否有这个属性,如果有就直接使用,如果没有会去到对象的__proto__指向原型对象中查找,如果找到则直接使用,找不到则继续向下的原型对象中查找(等会详说)
在原型对象中都有一个constructor属性,这是一个原型对象的构造器,constructor这个属性指向,这个原型的构造函数
通过内置构造函数创建函数
let fn = new Function('console.log(123)');
此处函数也是对象
console.log(fn);
fn.call()
console.dir(fn);
所有的数据类型数据,都是通过构造函数创建的对象
对象访问属性或方法的访问规则
现在对象自身查找,如果找到有这个属性或方法,则直接使用
如果找不到,这去对象的__proto__原型中查找,找到直接使用
若果还是找不到,则去原型对象的__proto__指向的原型中查找,找到这使用,
如果找不到,则一直向原型对象的原型中查找你,直到找到Object的prototype指向的原型找,
如果还是没有,则返回undefined
function Person(name){
this.name = name
}
Person.prototype.age = 18;
let per1 = new Person('zs');
给对象赋值一个 age = 20属性
per1.age = 20;
console.log(per1.age);// 20
let per2 = new Person('lisi');
console.log(per2.age); // 18
console.log(per1);
console.log(per2);
给实例对象的属性赋值,不会改变原型中的数据
只会给这个对象动态的添加属性:属性值
构造函数创建对象
let obj = new Object();
console.log(obj);
new Object() 中的() 可以省略,但是不建议省略
console.log(new Object);
function Person(name){
this.name = name;
}
let per = new Person
如果需要传递参数,则不能省略,否则创建的对象中的属性值为undefined
console.log(per);