kunquan
kunquan

Reputation: 1267

In ES6 class syntax why setPrototypeOf() work and other similar method don't

As I read MDN(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes#Sub_classing_with_extends) about inheriting property in class, they say that I need to use Object.setPrototypeOf()

class Book {
  constructor(title) {
    this.name = "Book";
    this.title = title;
  }
}

Object.setPrototypeOf(Book.prototype, {
  state: 'OH',
  country: 'US'
})

let newBook = new Book('Lolita')
console.log(newBook.state) //OH

But when I check MDN about Object.setPrototypeOf(), they say it's slow and should use some other like Object.create(). But when I try it doesn't work

class Book {
  constructor(title) {
    this.name = "Book";
    this.title = title;
  }
}

Book.prototype = Object.create({
  state: 'OH',
  country: 'US'
})

let newBook = new Book('Lolita')
console.log(newBook.state) //undefined

I think it's pretty strange since with normal prototype syntax Object.create() work well. And Book.prototype is object, so I don't see any reason why I can't add prototype like that.

Note: After I read the first answer by @Felix it's seem reasonable. But when I try to adjust the code a little bit I found other place where it should not work but turn out it work

class Book {
  constructor(title) {
    this.name = "Book";
    this.title = title;
  }
}

Object.setPrototypeOf(Book.prototype, {
  state: 'OH',
  country: 'US'
})

class LibraryBook extends Book{}
LibraryBook.prototype = Object.create(Book.prototype)
let firstBook = new LibraryBook('Lolita')
console.log(firstBook.state)

Can you explain me about this case why it work?

Upvotes: 1

Views: 402

Answers (1)

Felix Kling
Felix Kling

Reputation: 816404

When you use the class syntax, the prototype property of the resulting constructor function is not writable and not configurable. That means you cannot assign a new value to it, neither via an assignment expression nor via Object.defineProperty.

class Book {}

console.log(Object.getOwnPropertyDescriptor(Book, 'prototype'));


Can you explain me about this case why it work?

LibraryBook.prototype = Object.create(Book.prototype) has no effect. You can remove it and get the same result. LibraryBook.prototype is already an object that has Book.prototype as its prototype. That's what the ... extends Book clause does.

class Book {}
class LibraryBook extends Book {}

console.log(Object.getPrototypeOf(LibraryBook.prototype) === Book.prototype);

Upvotes: 2

Related Questions