版权声明:本文为博主原创文章,如需转载请务必注明原地址。 https://blog.csdn.net/qq_31393401/article/details/82986607
构造函数
function Foo (name, age) { // 构造函数命名:大写字母开头
this.name = name
this.age = age
this.class = 'class-1'
// return this // 默认有这一行
}
var f = new Foo('David', 18)
构造函数-扩展
var a = {}
其实是var a = new Object()
的语法糖var a = []
其实是var a = new Array()
的语法糖function Foo(){...}
其实是var Foo = new Function(…)的语法糖- 使用
instance
判断一个函数是否是一个变量的构造函数,如Date instanceof Object
,会返回true
原型规则
- 所有的引用类型(数组、对象、函数),都具有对象特性,即可自由扩展属性(
null
除外) - 所有的引用类型(数组、对象、函数),都具有一个
__proto__
属性(隐式原型),它是一个普通的对象 - 所有的函数,都有一个
prototype
属性(显式原型),它也是一个普通对象 - 所有的引用类型(数组、对象、函数),
__proto__
属性值指向它的构造函数的prototype
属性值 - 当试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么会去它的
__proto__
(即它的构造函数的prototype
)中寻找
// 循环对象自身的属性
function f (){...}
var item
for (item in f) {
// 高级浏览器已经在for in 中屏蔽了来自原型的属性
// 但还是建议加上这个判断,为了程序的健壮性
if (f.hasOwnProperty(item)) {
console.log(item)
}
}
原型链
// 构造函数
function Foo(name, age) {
this.name = name
}
Foo.prototype.alertName = function () {
alert(this.name)
}
// 创建示例
var f = new Foo('David')
f.printName = function () {
console.log(this.name)
}
// 测试
f.printName()
f.alertName()
f.toString() // 要去 f.__proto__.__proto__ 中查找
Function 与 Object 的关系
- 首先,js中,一切引用类型都是对象,包括函数、数组、对象。
- 一切对象都有一个根源,它是
Object.prototype
,称之为“根源对象”。 - 根源对象之上没有其他根源,即
Object.prototype.__proto__ === null
为true
,js中除了字面量以外的一切引用对象都来自这个根源对象。 Function.__proto__ === Function.prototype
为true
。实际上,Function.prototype
是一个内置函数,一切函数都派生自这个内置函数,它是一个内置函数工厂,这个内置函数对象的prototype
指向“根源对象”。
Function
和Object
,既是函数,因为都可以通过Function()
和Object()
的方式执行;
又是对象,因为可以扩展属性,如Function.a = 1
,Object.b = 2
这样。
说他们是函数,因为他们都是通过上面第4条说的“内置函数工厂”,派生出来的,因此具备函数的特性。
说他们是对象,因为他们都是通过第2条说的“根源对象”,派生出来的,因此具备对象的特性。
下面是我做的一张图,有不合理或不正确的地方欢迎指正
intanceof
用于判断引用类型属于哪个构造函数的的方法。
- 如:
f intanceof Foo
的判断逻辑是:
f
的__proto__
一层一层往上,能否找到对应的Foo.prototype
Object.getPrototypeOf
Object.getPrototypeOf(o)
等同于o.__proto__
面试题
- 描述new一个对象的过程:
- 创建一个新对象
- this指向这个新对象
- 执行代码,即对this赋值
- 返回this
function Foo(name){
this.name = name
// return this
}
var f = new Foo('David')
- 写一个原型链继承的demo
// 动物
function Animal(){
this.eat = function(){
console.log('animal eat')
}
}
// 狗
function Dog(){
this.bark = function(){
console.log('dog bark')
}
}
Dog.prototype = new Animal()
// 哈士奇
var hashiqi = new Dog()
hashiqi.eat() // 'animal eat'
hashiqi.bark() // 'dog bark'
原型实战
function Elem(id) {
// 获取DOM
this.elem = document.getElementById(id)
}
// 获取/修改DOM html
Elem.prototype.html = function(val){
var elem = this.elem
if(val) {
elem.innerHTML = val
return this // 链式操作
} else {
return elem.innerHTML
}
}
// 绑定事件
Elem.prototype.on = function(type,fn){
var elem = this.elem
elem.addEventListener(type,fn)
}
var div1 = new Elem('div1')
console.log(div1.html())
div1.html('<p>hello prototype</p>').on('click',function(){alert('点击了div1')})