javaScript面向对象
🍓面向对象的创建方式
- 📌字面量方式创建对象
一次只能创建一个对象var obj1 = {} obj1.name = 'Nancy' obj1.age = 23 obj1.sayHi = function() { console.log('Hello world!') }
- 📌内置构造函数创建对象
一次只能创建一个对象var obj2 = new Object() obj2.name = "Mike" obj2.age = 24 obj2.sayHi = function() { console.log('Hello world!') }
- 📌工厂函数创建对象
可以批量创建对象//工厂函数创建对象 function createObj(name, age){ var obj = {} obj.name = name obj.age = age obj.sayHi = function(){ console.log('Hello world!') } return obj } var obj3 = createObj('Lilei', 25)
- 📌自定义构造函数创建对象(推荐⭐⭐⭐)
可以批量创建对象,相比工厂函数,少了手动创建对象和返回对象两个步骤,但是要结合new
关键字一起使用才有效果function CreateObj(name, age){ this.name = name this.age = age this.sayHi = function() { console.log('Hello world!') } } //静态成员 CreateObj.PI = '3.1415926'; CreateObj.max = function(){ if(arguments.length == 0) { return null; } var max = arguments[0]; var arr = [...arguments]; arr.forEach(function(item, index, arr){ if(max < item) { max = item; } }); return max; } var obj4 = new CreateObj('Tom', 26) console.log(CreateObj.PI); console.log(CreateObj.max(2, 4))
🍓原型
每一个函数都有一个隐藏对象prototype
(原型),构造函数是一种特殊的函数,所以他也有隐藏对象prototype
如果对象的方法我们写在构造方法内,那么每创建一个对象就要加载这个方法
,如果我们把方法写在原型上,则所有的对象共用一个方法,节省了内存开支
因此:
- 📌成员变量:写在构造函数内部
- 📌成员方法:写在构造函数的原型上
🍓原型链
每个实例对象都有一个隐藏属性:__proto__
(原型对象)
由此引发三个问题:
- 📌实例对象:
p
- 📌构造函数:
Person
- 🍁实例对象身上的
__proto__
指向谁?
p.__proto__ => Person.prototype
- 🍁构造函数也是对象,它身上的
__proto__
指向谁?(类型是函数)
Person.__proto__ => Function.prototype
- 🍁构造函数的原型对象
prototype
,它身上的__proto__
指向谁?(类型是Object
)
Person.prototype.__proto__ => Object.prototype
- 🍁
Object
构造函数也是对象,它身上的__proto__
指向谁?(类型是函数)
Object.__proto__ => Function.prototype
- 🍁
Object
构造函数的原型对象prototype
,它身上的__proto__
指向谁?(类型是Object
)
Object.prototype
属于顶级原型,它已经没有__proto__
了,它的__proto__ = null
(特殊) - 🍁
Function
构造函数也是对象,它身上的__proto__
指向谁?(类型是函数)
Function.__proto => Function.prototype
(特殊) - 🍁
Function
构造函数的原型对象prototype
,它身上的__proto__
指向谁?
Function.prototype.__proto => Object.prototype
- 🍁实例对象身上的