Reputation: 2185
I have this prompt on code wars
"There's no such thing as private properties on a javascript object! But, maybe there are?
Implement a function createSecretHolder(secret) which accepts any value as secret and returns an object with ONLY two methods"
I'm pretty sure it wants me to use closures to achieve this and I have read about how to do this here:
Private variables and closures
https://developer.mozilla.org/en-US/Add-ons/SDK/Guides/Contributor_s_Guide/Private_Properties
This is my code:
function createSecretHolder(secret) {
return {
var _secret = secret;
this.getSecret = function(){
return _secret;
}
this.setSecret = function(secret){
_secret = secret;
}
}
}
However, I get this error:
[eval]:6
var _secret = secret;
^
SyntaxError: Unexpected token =
at Object. ([eval]-wrapper:6:22)
at
at evalScript (node.js:536:25)
at startup (node.js:80:7)
at node.js:906:3
I tried to make an object literal with a private value to hold the value of secret and mostly followed the examples from the sources I listed above. How do I create a closure with ONLY two methods to get and set data and where do I store the value of secret without adding another property?
Upvotes: 1
Views: 2524
Reputation: 133
Using _ to prepend a property is a common naming convention JavaScript developers follow to show the intention that the property should not be altered, and it is definitely related to this prompt, but it seems like it is not hinting that it's needed and it may not be required for this challenge specifically.
The SyntaxError you're seeing is related to the _secret initialization being within the object literals rather than outside. Object literal syntax is different from variable declaration & assignment and should be mixed. You can move the var _secret = secret;
to outside of and before the return statement (but still inside of the function createSecretHolder). (Super Hornet is right, but his code is missing the secret
parameter, so his code would get a Reference error saying that secret is not defined.) While your attempt is slightly more declarative, you can actually do without the const _secret = secret
. The first thing that the function does is to pair its argument with its parameter, in this case, declaring secret and assigning the input to it. So it is already "in closures".
Here's my take and it works almost the same, except I like to include the console.log() into my functions that I'm expecting to see a result.
function createSecretHolder(secret) {
// input: secret
// output: object (with only 2 methods)
return {
getSecret() { console.log(secret) },
setSecret(input) { secret = input }
}
}
const obj1 = createSecretHolder(5);
obj1.getSecret() // => 5
obj1.setSecret(2)
obj1.getSecret() // => 2
Same as:
function createSecretHolder2(secret) {
return {
getSecret() { return secret },
setSecret(input) { secret = input }
}
}
const obj2 = createSecretHolder2(91);
console.log(obj2.getSecret()) // => 91
console.log(obj2.setSecret(82)) // => undefined
obj2.setSecret('new Secret') // logs nothing, returns undefined
obj2.getSecret() // logs nothing, returns 'new Secret'
Upvotes: 0
Reputation: 239693
You are trying to return an object literal, in which you cannot have an assignment statement. To have the closure property, you need to store the variable in the function scope, like this
function createSecretHolder(secret) {
var _secret = secret;
return {
getSecret: function() {
return _secret;
},
setSecret: function(secret) {
_secret = secret;
}
}
}
Now, _secret
is in the scope of the getSecret
and setSecret
functions, because of the closure property. So they can access it.
Upvotes: 2
Reputation: 2907
The problem is return
keyword actually returns object with a structure which you didn't follow.
try this:
function createSecretHolder() {
var _secret = secret;
return {
getSecret : function(){
return _secret;
}
,
setSecret : function(secret){
_secret = secret;
}
}
}
Upvotes: 0