如何在循环中使用Object.create()?替代new关键字实现对象创建
用Object.create()循环创建对象的修正方案
嘿,我瞅了你的代码,第29行的报错主要是因为代码没写完,再加上用Object.create()的方式没捋对,咱们一步步把它改好:
先修正原始代码里的小问题
首先你的piece对象里name: king这里,king没加引号,会被当作未定义的变量,得改成字符串:
var piece = { size: 50, x: 0, y: 0, name: 'king' }
另外循环里的i和j没声明,会变成全局变量,最好用let或者var包裹起来。
改用Object.create()创建网格方块
原来你用对象字面量{}来创建每个方块,现在换成Object.create()的话,核心是基于你的square原型对象来生成新对象,然后给每个新对象设置独有的x和y坐标。
有两种写法,选你觉得顺手的就行:
写法一:创建后直接赋值(更直观)
function my_game() { var cols = 11; var rows = 11; var num = cols * rows; var size = 50; var spacing = 5; var square = { size: 50, x: 0, y: 0 } var piece = { size: 50, x: 0, y: 0, name: 'king' } function make_grid() { var squares = []; // 给循环变量加声明,避免全局污染 for (let i = 0; i < rows; i++) { for (let j = 0; j < cols; j++) { // 基于square原型创建新对象 const newSquare = Object.create(square); // 设置当前方块的坐标 newSquare.x = j * (size + spacing); newSquare.y = i * (size + spacing); squares.push(newSquare); } } // 可以返回数组方便后续使用 return squares; } // 调用函数测试 const grid = make_grid(); console.log(grid); }
写法二:用属性描述符初始化(更严谨)
如果想在创建对象时就直接定义属性,也可以用Object.create()的第二个参数,传入属性描述符对象:
function my_game() { var cols = 11; var rows = 11; var num = cols * rows; var size = 50; var spacing = 5; var square = { size: 50, x: 0, y: 0 } var piece = { size: 50, x: 0, y: 0, name: 'king' } function make_grid() { var squares = []; for (let i = 0; i < rows; i++) { for (let j = 0; j < cols; j++) { squares.push(Object.create(square, { x: { value: j * (size + spacing), writable: true, // 允许后续修改x值 enumerable: true // 允许遍历到这个属性 }, y: { value: i * (size + spacing), writable: true, enumerable: true } })); } } return squares; } const grid = make_grid(); console.log(grid); }
为啥这么改?
Object.create(square)会创建一个新对象,这个新对象的原型指向square,所以它会继承square里的size属性,同时你可以给每个新对象设置自己的x和y,完美替代原来用new或者字面量创建对象的方式。
内容的提问来源于stack exchange,提问作者Gallaxhar
相关产品推荐
相关产品推荐

