gpt4 book ai didi

javascript - Object.create() 未按预期工作

转载 作者:行者123 更新时间:2023-11-28 17:33:08 25 4
gpt4 key购买 nike

我在 Stack Overflow 上阅读了一些问题,但我无法找出问题所在。昨天用户 Scott Marcus answered对于我的问题并给出解释性答案,我使用 Object.create() 测试了该解决方案,并且我决定这就是我想要编写对象的方式。

这是我所做的工作测试:

var Obj = {
/**
* @type {string}
*/
name: '',

uppercase: function () {
this.name = this.name.toUpperCase();
return true;
},

/**
* setName
* Set the `name` property.
*
* @param param
*/
set setName (param) {
this.name = param;
},

get getName () {
return this.name;
}
};

var a = Object.create(Obj);
var b = Object.create(Obj);
a.setName = "Will";
b.setName = "Byers";

console.log("Name in object a is: ".concat(a.getName));
console.log("Name in object b is: ".concat(b.getName));

然后我在脚本上尝试了相同的解决方案,但是这次 Object.create() 没有创建两个单独的对象,我不明白为什么。如果您单击“CLICK”按钮,它会在控制台中打印两个应该不同的对象(对象 b 应仅包含 `{ asd: "QWE"}),但它们其实是一样的。

谁能解释一下我做错了什么吗?

//  Declaring my object
var Field = {
/**
* @type {Object}
*/
collection: {},


/**
* collect
* Push the | indexName: value | into collection object.
*
* @param {object} obj
*/
collect: function (obj) {
//console.log(obj);
var indexNames = Object.keys(obj);
var selectors = Object.values(obj);

for (var i=0; i<indexNames.length; i++) {
var el = document.querySelectorAll(selectors[i]);
this.collection[indexNames[i]] = this.fldValue(el);
}
},

/**
* fldValue
* Get the value of the injected object after having recognized its tagName and type.
*
* @param {object} HTMLObject
* @returns {*}
*/
fldValue: function (HTMLObject) {
HTMLObject = HTMLObject[0];
switch (HTMLObject.tagName) {
case "INPUT":
switch (HTMLObject.type) {
case "text":
case "password":
case "hidden":
return HTMLObject.value;

case "checkbox":
return HTMLObject.checked;

default:
throw "Unknown input type: ".concat(HTMLObject.type);
}

case "DIV":
case "P":
case "SPAN":
case "H1":
case "H2":
case "H3":
case "H4":
case "H5":
case "H6":
return HTMLObject.textContent;

default:
throw "Unknown element tagName: ".concat(HTMLObject.tagName);
}
},

/**
*
* @param {string} className
* @returns {*}
*/
reset: function (className) {
var elements = document.getElementsByClassName(className);

for (var i=0; i<elements.length; i++) {
var el = elements[i];

switch (el.tagName) {
case "INPUT":
switch (el.type) {
case "text":
case "password":
case "hidden":
el.value = '';
break;

case "checkbox":
el.checked = false;
break;

default:
throw "Unknown input type: ".concat(el.type);
}
break;

case "DIV":
case "P":
case "SPAN":
case "H1":
case "H2":
case "H3":
case "H4":
case "H5":
case "H6":
el.innerHTML = '';
break;

default:
throw "Unknown element: ".concat(el.tagName);
}
}
},

get getCollection() {
return this.collection;
}
};


// --------------------
// Object instantiation
var a = Object.create(Field);
var b = Object.create(Field);

document.getElementById('send')
.addEventListener('click', function (ev) {
a.collect({
name: '[name="name"]',
password: '.password',
title: '.title',
description: '.container',
note: '#paragraph',
chk_1: '[name="chk1"]',
chk_2: '[name="chk2"]'
});

b.collect({
asd: '.title'
});

// !! They should be different but they're actually the same object !!
console.log(a.getCollection);
console.log(b.getCollection);
});

document.getElementById('reset')
.addEventListener('click', function (ev) {
a.reset('reset');
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1 class="title">QWE</h1>

<input type="text" class="name reset" name="name">
<input type="password" class="password" name="password">

<input type="checkbox" class="reset" name="chk1">
<input type="checkbox" name="chk2">

<div class="container reset">HEY</div>

<p id="paragraph">OPS</p>

<button id="send">CLICK</button>
<button id="reset">RESET</button>


<script src="Field.js"></script>
<script>

</script>

最佳答案

因为collection是一个对象,被Field引用,所以ab继承对该单个对象的引用并共享它。最初,在设置 Field 后,内存中会有类似这样的内容(省略了很多细节):

                                       +−−−−−−−−−−−−−−−−−−−−−+Field−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−>|       (object)      |                                       +−−−−−−−−−−−−−−−−−−−−−+    +−−−−−−−−−−+                                       | collection          |−−−>| (object) |                                       | collect             |−+  +−−−−−−−−−−+                                       | ...                 | |                                       +−−−−−−−−−−−−−−−−−−−−−+ |  +−−−−−−−−−−−−+                                                               +−>| (function) |                                                                  +−−−−−−−−−−−−+

Then after

var a = Object.create(Field);
var b = Object.create(Field)

你有这样的东西:

                                       +−−−−−−−−−−−−−−−−−−−−−+                  Field−−−−−−−−−−−−−−−−−−−−−−−−−−−−+−−+−>|       (object)      |                                                   |  |  +−−−−−−−−−−−−−−−−−−−−−+    +−−−−−−−−−−+                                   |  |  | collection          |−−−>| (object) |                                   |  |  | collect             |−+  +−−−−−−−−−−+                                   |  |  | ...                 | |                                                 |  |  +−−−−−−−−−−−−−−−−−−−−−+ |  +−−−−−−−−−−−−+              +−−−−−−−−−−−−−−−+  |  |                          +−>| (function) |a−−−−−−−−−−−−>| (object)      |  |  |                             +−−−−−−−−−−−−+              +−−−−−−−−−−−−−−−+  |  |              | [[Prototype]] |−−+  |              +−−−−−−−−−−−−−−−+     |                                    |              +−−−−−−−−−−−−−−−+     |b−−−−−−−−−−−−>| (object)      |     |              +−−−−−−−−−−−−−−−+     |              | [[Prototype]] |−−−−−+              +−−−−−−−−−−−−−−−+

Notice that a and b inherit collection, which means they refer to the same collection object.

Instead, you need a and b to each have their own collection object:

var a = Object.create(Field);
a.collection = {};
var b = Object.create(Field);
b.collection = {};

//  Declaring my object
var Field = {
/**
* @type {Object}
*/
collection: {},


/**
* collect
* Push the | indexName: value | into collection object.
*
* @param {object} obj
*/
collect: function (obj) {
//console.log(obj);
var indexNames = Object.keys(obj);
var selectors = Object.values(obj);

for (var i=0; i<indexNames.length; i++) {
var el = document.querySelectorAll(selectors[i]);
this.collection[indexNames[i]] = this.fldValue(el);
}
},

/**
* fldValue
* Get the value of the injected object after having recognized its tagName and type.
*
* @param {object} HTMLObject
* @returns {*}
*/
fldValue: function (HTMLObject) {
HTMLObject = HTMLObject[0];
switch (HTMLObject.tagName) {
case "INPUT":
switch (HTMLObject.type) {
case "text":
case "password":
case "hidden":
return HTMLObject.value;

case "checkbox":
return HTMLObject.checked;

default:
throw "Unknown input type: ".concat(HTMLObject.type);
}

case "DIV":
case "P":
case "SPAN":
case "H1":
case "H2":
case "H3":
case "H4":
case "H5":
case "H6":
return HTMLObject.textContent;

default:
throw "Unknown element tagName: ".concat(HTMLObject.tagName);
}
},

/**
*
* @param {string} className
* @returns {*}
*/
reset: function (className) {
var elements = document.getElementsByClassName(className);

for (var i=0; i<elements.length; i++) {
var el = elements[i];

switch (el.tagName) {
case "INPUT":
switch (el.type) {
case "text":
case "password":
case "hidden":
el.value = '';
break;

case "checkbox":
el.checked = false;
break;

default:
throw "Unknown input type: ".concat(el.type);
}
break;

case "DIV":
case "P":
case "SPAN":
case "H1":
case "H2":
case "H3":
case "H4":
case "H5":
case "H6":
el.innerHTML = '';
break;

default:
throw "Unknown element: ".concat(el.tagName);
}
}
},

get getCollection() {
return this.collection;
}
};


// --------------------
// Object instantiation
var a = Object.create(Field);
a.collection = {};
var b = Object.create(Field);
b.collection = {};

document.getElementById('send')
.addEventListener('click', function (ev) {
a.collect({
name: '[name="name"]',
password: '.password',
title: '.title',
description: '.container',
note: '#paragraph',
chk_1: '[name="chk1"]',
chk_2: '[name="chk2"]'
});

b.collect({
asd: '.title'
});

// !! They should be different but they're actually the same object !!
console.log(a.getCollection);
console.log(b.getCollection);
});

document.getElementById('reset')
.addEventListener('click', function (ev) {
a.reset('reset');
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1 class="title">QWE</h1>

<input type="text" class="name reset" name="name">
<input type="password" class="password" name="password">

<input type="checkbox" class="reset" name="chk1">
<input type="checkbox" name="chk2">

<div class="container reset">HEY</div>

<p id="paragraph">OPS</p>

<button id="send">CLICK</button>
<button id="reset">RESET</button>


<script src="Field.js"></script>
<script>

</script>

当然,每次创建Field时都必须编写每个实例的初始化逻辑有点痛苦,这就是为什么我们有构造函数/ 语法,或者构建器函数(如果您不喜欢使用 new)。

function newField() {
var f = Object.create(Field);
f.collection = {};
return f;
}

然后

a = newField();
b = newField();

关于javascript - Object.create() 未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49829294/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com