this is my code:
<script type="text/javascript">
var Note=function(){}
Note.prototype = {
get id()
{
if (!("_id" in this))
this._id = 0;
return this._id;
},
set id(x)
{
this._id = x;
}
}
var a=new Note()
alert(a.id)
</script>
this style is like to python ,
this is my first time to see this code ,
and can you give me more example about 'get' and 'set' in javascript .
thanks
Yes it does. This feature was added in ECMAScript 5.
PropertyAssignment:
PropertyName : AssignmentExpression
get PropertyName() { FunctionBody }
set PropertyName( PropertySetParameterList ) { FunctionBody }
Here are a few things to remember when using this syntax.
If your object literal has a value property it cannot have getter or setter and vice versa.
Your object literal cannot have more than one getter or setter with the same name.
A better way to actually use this feature is through the Object.defineProperty function.
function Person(fName, lName) {
var _name = fName + " " + lName;
Object.defineProperty(this, "name", {
configurable: false, // Immutable properties!
get: function() { return _name; }
});
}
This allows you to have nice clean objects with encapsulation.
var matt = new Person("Matt", "Richards");
console.log(matt.name); // Prints "Matt Richards"
It can in certain engines, and it's in the spec for EcmaScript 5, so it should be more widely adopted in the future. The Compatibility Table doesn't direclty address this, but it will likely follow defineProperties, which provides an API for doing the same thing. As pointed out previously, John Resig has a nice article on the new object and property APIs.
Javascript does in fact support getters and setters now. John Resig has a good blog post about them here.
John's article does a good job at mentioning several different ways of defining getters/setters on Javascript objects, but doesn't do a good job at describing when each method is applicable. I believe that is much more effectively accomplished in a more recent blog post by Robert Nyman:
Getters and setters with JavaScript
(this article also introduces the ECMAScript Standard Object.defineProperty)
Yes it can. Here is a nice post about it from John Resig, the creator of jQuery:
JavaScript Getters and Setters
Related
Edit In regard of Barmar request, I upload this screenshot. As Jake claims, this is about that statement.
In this article MDN explains some details on JS inheritance, including a meant demonstration of why JS classic model of inheritance is safer than JS classes. They did many useful things in this text, but I don't see this particular point demonstrated. Could somebody point out the MDN arguments that demonstrate how traditional syntax is safer than classes syntax?
Thank you
Bonus: I did this short version of "The employee example" implemented in the mentioned article. According to this, traditional syntax is not safer, but rather longer and difficult to follow:
//TRADITIONAL SYNTAX
function Participant ({gender, tastes}){
this.gender = gender;
this.tastes = tastes || [];
}
function NotPayer({gender, tastes, role}){
this.role = role || 'kid';
this.base = Participant;
this.job = 'Not Valid';
this.base({gender, tastes});
}
NotPayer.prototype = Participant.prototype;
const kid1 = new NotPayer({role: 'nephew', gender: 'male', tastes: ['golf']});
console.log(kid1.gender); //male
const kid2 = new Participant({gender: 'female'});
console.log(kid2.gender); // female
//MODERN SYNTAX
class Participant {
constructor({gender, tastes}){
this.gender = gender;
this.tastes = tastes || [];
}
}
class NotPayer extends Participant {
constructor({gender, tastes, role}){
super({gender, tastes});
this.role = role || 'kid';
}
}
const kid1 = new NotPayer({role: 'nephew', gender: 'male', tastes: ['golf']});
console.log(kid1.gender);//male
const kid2 = new Participant({tastes: ['dance'], gender: 'female2'});
console.log(kid2.gender);// 'female2'
The text in article is a caption for the code sample below it. It says
JavaScript (using this may cause an error for the following examples)
and then goes on to show an example of class syntax. Immediately following that example is a caption saying
JavaScript ** (use this instead)
followed by an example of a (constructor) function syntax.
It then shows how Java does classes. Then the article talks a little about prototypal inheritance, a key part of JavaScript's object oriented design prior to the introduction of classes, and follows up with examples of that type of inheritance.
It is in these examples where, if one used the class syntax example introduced originally, the code would fail.
Just for giggles, here's a Stack Snippet showing what happens:
class Employee {
constructor() {
this.name = '';
this.dept = 'general';
}
}
function Manager() {
Employee.call(this);
this.reports = [];
}
Manager.prototype = Object.create(Employee.prototype);
Manager.prototype.constructor = Manager;
console.log(new Manager());
The error that arises (Uncaught TypeError: Class constructor Employee cannot be invoked without 'new') when you click Run code snippet here (on a suitably modern browser) is what that "using this may cause an error" text is talking about. That "for the following examples" is a key part of the phrase.
The MDN warning regards that the examples developed in the article could not run in some engines, rather than suggests that traditional syntax is better than modern syntax. As Ashish and Jake pointed out this is related to JS engines support for classes syntax.
Even though, I think that the MDN article could be even more explicit about that (since, the argumentation regards many complex subjects.)
I've searched a lot for how to do properties in Javascript. Most all of the revealing module pattern I've seen has exclusively exposed functions, and from experience I know if I expose an object, I'm only really getting a copy of the value right there and then, thus simply I could have a function getMyThing() and setMyThing and expose that. However I'm wanting to expose real properties
I've seen the oldschool defineGetter which I'm avoiding and the newer Object.defineProperty( which I had some real troubles with. (I could easily use it against an artitary object but not THIS inside my "module" nor a property inside my module I wanted to reveal.
var myobj = (function() {
var name = "default name"
var sayName = function() { return "hello " + name }
return {
badname : name, //this won't change
sayName : sayName,
get name() { return name;},
set name(value) { name = value ;}
}
})()
alert("should be default because its just a copy: " + myobj.badname)
alert("should be default: " + myobj.name)
myobj.name = "karl"
alert("should be default because its just a copy: " + myobj.badname)
alert("should be karl: " + myobj.name)
Anyhow I see in a few places you can use get and set keywords and I have the following example that is working for me at least in firefox and ie10.
My question: Is this an acceptable approach or are there hidden gotchas I am not aware of. Is it the approach that would be most accepted in modern browsers?
What is this feature called? and what is the official name of the Object.defineProperty feature?
I'm presuming the use of the get and set keyword is ECMAScript5 getters and setters, but what is the other one called?
and is the get and set keywords what is mentioned in this compatibility chart http://kangax.github.io/es5-compat-table/ under the category "Getter in property initializer" and "Setter in property initializer"?
example on JSfiddle - http://jsfiddle.net/klumsy/NagbE/1/
The pattern you're using looks good. It'll be supported by all ES5 browsers.
The get and set syntax inside the object literal is often referred to as ES5 object literal extensions for defining accessor properties. An accessor property is a property that is made up of a getter and/or setter. The term for the traditional kind of property which isn't a getter/setter is a data property.
And, yes, that is what kangax's compatibility table is referring to by "... in property initializer" (if you mouse-over the grey "c" with a circle around it on that page, you can see the actual test that's being run).
The meta-property features provided by Object.defineProperty are referred to as property descriptors. There are two kinds of property descriptors in ES5: data descriptors and accessor descriptors, which are made up of the following descriptor properties:
Data Descriptor: value, writable, enumerable, configurable
Example:
Object.defineProperty(obj, 'prop', {
value: 'some value',
writable: true,
enumerable: false,
configurable: true
});
Accessor Descriptor: get, set, enumerable, configurable
Example:
Object.defineProperty(obj, 'prop', {
get: function() { return 'foo'; },
set: function() { /* do something... */ },
enumerable: false,
configurable: true
});
I understand how to instantiate objects and call them, but I just cannot find a reason to use them in my script. I could do
var obj = {
hi: function() {
return "Hello";
}
};
but why can't I just do it the same way like:
function hi() {
return "Hello";
}
I've never understood the reasons why I should use prototyping either. Most of the things I do in JavaScript I can do well without objects. But I want to use objects. What are objects for and what are the reasons why I should use them?
Objects are useful for example for making a single unit out of values that belong together. Example:
function Person(firstName, lastName, gender, age) {
this.firstName = firstName;
this.lastName = lastName;
this.gender = gender;
this.age = age;
}
Person.prototype = {
getFullName: function() { return this.firstName + ' ' + this.lastName; },
isMale: function() { return this.gender == 'Male'; },
isFemale: function() { return this.gender == 'Female'; }
};
var amanda = new Person('Amanda', 'Smith', "Female", 42);
var john = new Person('John', 'Doe', 'Male', 72);
alert(amanda.getFullName());
alert(john.isMale());
Compared to the less structured:
function getFullName(firstName, lastName) {
return firstName + ' ' + lastName;
}
function isMale(gender) {
return gender == 'Male';
}
function isFemale(gender) {
return gender == 'Female';
}
var amandaFirstName = 'Amanda';
var amandaLastName = 'Smith';
var amandaGender = 'Female';
var amandaAge = 42;
var johnFirstName = 'John';
var johnLastName = 'Doe';
var johnGender = 'Male';
var johnAge = 72;
alert(getFullName(amandaFirstName, amandaLastName));
alert(isMale(johnGender));
Objects are useful because
They are stateful.
They can store relations between strings and data.
It can be easier to decompose a problem by breaking it up into objects that collect related operations and state.
If you don't need non-global state, have no need of lookup tables, and your problem is small or more easily decomposed functionally then don't use objects.
Without what you are referring to as objects, you are going to have loose functions all over the place. This very often will result in code that is very difficult to maintain. At a bare minimum objects give you the ability to lump functions together in order to simulate namespaces-- and that's at a bare minimum.
In your simple example, it makes indeed no sense to write a semi "class" / object to hold that method. But when your code grows, you're getting more and more functions and methods, you don't really want to have them all in one big (global) namespace. That is just so impossible to maintenain, no one will understand that code including you at some later point.
That is the first good reason to wrap methods together in an object/"class". Another good reason is re-usabilty. If you're writting objects which are able to inherit their methods, you can re-create another object and abstract it from there on. Most simple concept, but you want to use it if you're describing "things" in your application as module/object.
It tries to simulate the OOP paradigm that's all. There are various ways of doing this. But ask yourself, doe 'hi' belong in 'obj' or can it be a standalone function? Its all about how closely related is the function to the object. Does the function needs to access the objects private variables and such?
This is less of a "objects in Javascript" and more of an objects in general" question.
I'd say the most relevant Javascript The only thing Javascript specific about objects is their neat use when namespacing. For example, most Javascript libraries pack all their stuff in a single object to avoid namespace collision:
dojo.create( ... )
dojo.connect( ... )
As for the other questions of why OOP, there are 2 basic things I think OOP excels at (generic, dumb, examples follow):
Dynamic dispatching - get rid of "ifs" and put responsabilitty where it belongs
When you look at a code that has tons of "switchs":
function doStuff(animal){
if animal is a tiger:
print_tiger_roar();
else if animal is a cow
print_cow_moo();
if animal is a tiger:
print_tiger_wants_meat();
else if animal is a cow
print cow_wants_grass();
It might be a good idea to bundle each different kind of behaviour in a different kind of object and use dynamic dispatching instead:
function doStuff(animal):
animal.print_speak();
animal.print_food_type();
Now, if you come up with another kind of animal in the future, you don't need to go looking around your code to add it - all you need to do is create a new class with the appropriate print_speack and print_food_type methods and the rest of the code won't notice a thing.
Inheritance + reusing methods
In a normal OO language each object stores (and spends memory) for its instance variables, while all methods + static variables are stored in a single place by the class. Javascript doesn't have classes, but it has prototypes and they serve the same basic function in the end.
Some generic thoughts concerning "Why" part:
Objects exist to communicate. It is a common vocabulary for everyone involved in a project. People are used to operate with things (objects) and their operations (messages or methods), rather than just with disconnected actions (functions).
I'm trying to find a way to to property overloading like it's done in PHP: http://www.php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.members
i.e.
var myobj = function () {}
myobj.prototype.getProperty = function (propertyName) { console.log('Property Requested: ', propertyName); }
var otherObj = function () {};
myobj.hello; // Property Request: hello
otherObj.hello; // undefined
Is this possible?
This sort of thing can only be done in ECMAscript 5 which is not supported in all browsers (e.g. IE). Using Object.defineProperty you can create properties with accessor functions - so you could implement a property like length in arrays that varies, depending on the object state.
There's a good presentation from Doug Crockford about these features and with links to more detailed descriptions here.
This question already has answers here:
Is there an equivalent of the __noSuchMethod__ feature for properties, or a way to implement it in JS?
(6 answers)
Closed 6 years ago.
I'm looking for a way to handle calls to undefined methods and properties in JavaScript.
These would be similar to the PHP magic methods __call, __callStatic, __get.
An example of the code using this might be:
var myObject = {};
myObject.__call = function (called, args) {
alert(called);
alert(args);
return(true);
}
myObject.meow("kitty", "miau");
This would result in the first alert dialog displaying "meow" and the second to display "kitty, miau".
Proxy can do it! Proxy can do EVERYTHING! An answer is given here: Is there a javascript equivalent of python's __getattr__ method? . To rephrase in my own words:
var myObject = new Proxy({},{get(target,name) {
return function() {
alert(name)
console.log(arguments) // alerts are bleh
return true
}
}})
myObject.meow("kitty", "miau") // alerts "meow", logs ["kitty","miau"] to the console, and returns true
Check out the MDN docs: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
Works in chrome, firefox, and node.js. Downsides: doesn't work in IE - freakin IE. Soon.
If you just want something like PHP's features, read the following solution I came up with. I'm assuming that you'll be putting this functionality on your own objects. Well, as long as they're not functions, you can have the following convention for convenience, and it should work on all browsers:
instead of myobj.foo or myobj['foo'], just use myobj('foo'), and make your object callable when you define it. But you'll have to avoid the use of "new" because "new" can never return a function in Javascript.
var NewFlexible = function() {
var custom = {};
return function(prop) {
if (!(prop in custom)) custom.prop = null;
return custom.prop;
};
};
And then you can create objects like so:
myObj = NewFlexible();
Using something similar to the Douglas Crockford pattern, you could create "classes" that extend this:
var NewDerived = function(options) {
var result = {};
NewFlexible.apply(result, arguments); // parent constructor
// go on to do what you have to do
return result;
};
Or, to forget about constructors, you can just make a wrapper around objects:
var MakeFlexible = function (obj) {
return function(prop) {
if ('prop' in obj) return obj.prop;
obj.prop = null; return obj.prop;
};
}
You'll just have to publish this documentation for all users of your code. It's actually good to expose your functionality through this convention because you don't want to freak people out by using nonstandard javascript.
There is a magic function in Javascript called __noSuchMethod__. Here's an example:
var foo = { __noSuchMethod__ : function(name,params) { alert('invalid function call'); } }
foo.bar();
EDIT: As #jldupont mentioned, this is actually only in Rhino and SpiderMonkey (Mozilla's JS engine); it is not supported in the ECMAScript standard. There are some requests that it be in ECMAScript 4.
I should add for people still looking for a solution, there is this:
var myObject = {};
myObject['dynamicMethod'] = new function (parameters) {
alert(parameters);
};
The only difference here is that you may have to iterate over what you intend on adding. This is pre-generating the methods, instead of simply dynamically handling them.
If you are looking specifically for a method, you will have to wait until ES7, because it looks they arent going to include it that way in harmony, anyway, there is a currently working-standard functionality on this, trought the built-in object Proxy, that is added in ES6, i wrote an answer, in this question, that takes the problem in a wider manner.
Basically involves wrapping the object into a proxy, an loading a handler
get: function(obj, propname) {custom handling}
into the proxy trought it´s constructor, to handle, filter or implement all requests of properties into it.
And it adds even more functionality.... For the complete answer, go into the link.