JS面向对象(三)

88 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情

function foo() {
  function bar() {}
  return bar
}

var fn1 = foo()
var fn2 = foo()

console.log(fn1 === fn2) //false

有个疑问fn1 和 fn2的返回值为什么会不同,如果创建多个构造函数每个构造函数内部都会创建一个新的bar函数,如何能解决这个问题呢?

对象的原型

  • JavaScript当中每个对象都有一个特殊的内置属性 [[prototype]](隐式原型),这个特殊的对象可以指向另外一个对象。
var obj = { name: "sabo" } 
var info = {} 


// __proto__ 这个操作方式是浏览器提供给我们的
console.log(obj.__proto__) // {}
console.log(info.__proto__) // {}

ES5之后提供的Object.getPrototypeOf方法查看原型

console.log(Object.getPrototypeOf(obj))

  • 原型有什么作用?
  1. 当我们从一个对象中获取某一个属性时, 它会触发 [[get]] 操作
  2. 在当前对象中去查找对应的属性, 如果找到就直接使用
  3. 如果没有找到, 那么会沿着它的原型去查找 [[prototype]]
obj.__proto__.age = 12

console.log(obj.age)//12

函数的原型

函数也是一个对象,所以函数作为对象来说,它也有[[prototype]](隐式原型)

function foo() {}

console.log(foo._proto_)

函数本身还有有个原型属性:prototype

function foo() {}

console.log(foo.prototype)

上篇介绍构造函数时new操作符的时候讲过

当一个函数被new操作符调用会执行哪些操作

  • 在内存中创建一个新的对象(空对象)
  • 这个对象内部的[[prototype]]属性会被赋值为该构造函数的prototype属性;;
  • 构造函数内部的this,会指向创建出来的新对象;
  • 执行函数的内部代码(函数体代码);
  • 如果构造函数没有返回非空对象,则返回创建出来的新对象;

也就是说函数的原型是等于隐式原型的

function foo() {}

console.log(foo._proto_ === foo.prototype) 

constructor属性

事实上原型对象上面是有一个属性的:constructor

默认情况下原型上都会添加一个属性叫做constructor,这个constructor指向当前的函数对象;

原型和构造函数

了解原型我们就可以解决上面的问题

function foo() {}

foo.prototype.bar = function() {
  return bar
}

var fn1 = foo()
var fn2 = foo()

console.log(fn1 === fn2)// true