js-原型和原型链

版权声明:本文为博主原创文章,如需转载请务必注明原地址。 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 的关系

  1. 首先,js中,一切引用类型都是对象,包括函数、数组、对象。
  2. 一切对象都有一个根源,它是Object.prototype,称之为“根源对象”。
  3. 根源对象之上没有其他根源,即Object.prototype.__proto__ === nulltrue,js中除了字面量以外的一切引用对象都来自这个根源对象。
  4. Function.__proto__ === Function.prototypetrue。实际上,Function.prototype是一个内置函数,一切函数都派生自这个内置函数,它是一个内置函数工厂,这个内置函数对象的prototype指向“根源对象”。

FunctionObject,既是函数,因为都可以通过Function()Object()的方式执行;
又是对象,因为可以扩展属性,如Function.a = 1Object.b = 2这样。

说他们是函数,因为他们都是通过上面第4条说的“内置函数工厂”,派生出来的,因此具备函数的特性。

说他们是对象,因为他们都是通过第2条说的“根源对象”,派生出来的,因此具备对象的特性。

下面是我做的一张图,有不合理或不正确的地方欢迎指正
在这里插入图片描述

intanceof

用于判断引用类型属于哪个构造函数的的方法。

  • 如:f intanceof Foo的判断逻辑是:
    f__proto__一层一层往上,能否找到对应的Foo.prototype

Object.getPrototypeOf

Object.getPrototypeOf(o)等同于o.__proto__

面试题

  • 描述new一个对象的过程:
    1. 创建一个新对象
    2. this指向这个新对象
    3. 执行代码,即对this赋值
    4. 返回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')})

猜你喜欢

转载自blog.csdn.net/qq_31393401/article/details/82986607
今日推荐