Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/387.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在构造函数中创建只读(get)属性_Javascript - Fatal编程技术网

Javascript 在构造函数中创建只读(get)属性

Javascript 在构造函数中创建只读(get)属性,javascript,Javascript,我试图用Javascript在构造函数上创建一个只读属性。我已经混音了,但这不起作用: 职能人员(数据){ var self=这个; self.firstName=data.firstName | |“John”; self.lastName=data.lastName | |“Doe”; get fullName(){return self.firstName+“”+self.lastName;} } var mike=新人({firstName:“mike”,lastName:“Michae

我试图用Javascript在构造函数上创建一个只读属性。我已经混音了,但这不起作用:

职能人员(数据){
var self=这个;
self.firstName=data.firstName | |“John”;
self.lastName=data.lastName | |“Doe”;
get fullName(){return self.firstName+“”+self.lastName;}
}
var mike=新人({firstName:“mike”,lastName:“Michaelson”});
document.write(mike.fullName);
这将引发异常:

未捕获的语法错误:意外的标识符

我尝试过其他选择,包括:

{ get fullName() { return self.firstName + " " + self.lastName; } }
以及:

以及:

但这些选项都不起作用

这一个确实有效:

职能人员(数据){
var self=这个;
self.firstName=data.firstName | |“John”;
self.lastName=data.lastName | |“Doe”;
defineProperty(self,“fullName”,{get:function(){return self.firstName+“”+self.lastName;}}});
}
var mike=新人({firstName:“mike”,lastName:“Michaelson”});

document.write(mike.fullName)
我建议将其设置为一个POJO,并始终传递选项,但您仍然会有
Object.defineProperties
的“笨拙”,只是没有实际调用它的仪式(我个人更喜欢速记方式)

EDIT:现在我已经详细考虑了它,我认为您想要包含
defineProperty
语法的原因是您想要对名字和姓氏具有读/写访问权限,但对
全名具有只读访问权限。如果这个假设是正确的,我通常会使用这个模式

var Person = function (data) {
    if (data === undefined) {
        data = {};
    }

    data = _.defaults(data, {
        firstName: 'John',
        lastName: 'Doe'
    });

    return {
        get firstName() { return data.firstName; },
        set firstName(name) { data.firstName = name; },

        get lastName() { return data.lastName; },
        set lastName(name) { data.lastName = name; },

        get fullName() { return data.firstName + ' ' + data.lastName; }
    }
}

p = Person();
p.fullName === 'John Doe'; // true
p.firstName = 'Jane';
p.fullName === 'Jane Doe'; // true
但是,需要注意一些注意事项,主要是对象引用

data = { firstName: 'Jane' };
p = Person(data);
p.fullName === 'Jane Doe'; // true
data.lastName = 'Goodall';
p.fullName === 'Jane Doe'; // false!
console.log(p.fullName); // 'Jane Goodall'

我通常更喜欢将参数作为不可变的东西传入,或者通过将这些特性从对象复制到不可变的东西中来冻结这些特性,这样通过对象引用进行的更新不会在您的行为中造成细微的错误。

您可以将其放入
原型中(
object.prototype={get x(){返回这个。x;}
-但是在声明完整原型时只能执行一次)或者使用
defineProperty
。如果要创建只读属性,实际上应该使用
defineProperty
使其不可写。这是唯一有效的语法方法。@Jeroen您是否希望对名/姓具有读/写权限,但对
fullName
具有只读权限?如果是,请重新读取my答案,因为我已经更新了它以适应这种情况。@Drogans感谢您的想法和想法。您对读/写访问的假设是正确的,尽管我已经能够从您对这些情况的原始答案中推断出来。我对您的答案投了更高的票,它很有用,但它并不是我问题的答案,因为您是
函数不再用作构造函数,因为它破坏了继承。-我想我只是被C#的属性语法破坏了…所以基本上“不可能在构造函数本身中使用速记”?另一方面,在您的示例中,返回的POJO的原型应该是
对象
,而不是
,对吗?如果您运行这个,并询问
人。原型
,它会说它是
对象。如果您愿意,您也可以
新建它。它的行为应该与您的问题中的代码示例完全相同如上所述。
(new Person())instanceof Person;
,与之相反。我可能误解了什么?不,你没有误解,返回的对象实际上就是
{}
对象。允许轻松定义的唯一方法是正确使用原型并在那里添加getter和setter,或者使用
defineProperty
。您正在寻找Javascript中不存在的语法糖。@Jeroen您是对的!我没有意识到
instanceof
不起作用。这似乎是一个不同的赌注在这两个实现之间。
var Person = function (data) {
    if (data === undefined) {
        data = {};
    }

    data = _.defaults(data, {
        firstName: 'John',
        lastName: 'Doe'
    });

    return {
        get firstName() { return data.firstName; },
        get lastName() { return data.lastName; },
        get fullName() { return data.firstName + ' ' + data.lastName; }
    }
}
var Person = function (data) {
    if (data === undefined) {
        data = {};
    }

    data = _.defaults(data, {
        firstName: 'John',
        lastName: 'Doe'
    });

    return {
        get firstName() { return data.firstName; },
        set firstName(name) { data.firstName = name; },

        get lastName() { return data.lastName; },
        set lastName(name) { data.lastName = name; },

        get fullName() { return data.firstName + ' ' + data.lastName; }
    }
}

p = Person();
p.fullName === 'John Doe'; // true
p.firstName = 'Jane';
p.fullName === 'Jane Doe'; // true
data = { firstName: 'Jane' };
p = Person(data);
p.fullName === 'Jane Doe'; // true
data.lastName = 'Goodall';
p.fullName === 'Jane Doe'; // false!
console.log(p.fullName); // 'Jane Goodall'