Difference between Property and Attribute in JavaScript

Source: Internet
Author: User

Difference between Property and Attribute in JavaScript
Property and attribute are very confusing. the Chinese translation of the two words is also very similar (property: attribute, attribute: feature). However, the two are actually different things and belong to different categories. Property is an attribute in DOM and an object in JavaScript. attribute is a feature on HTML tags and its value can only be a string. Based on JavaScript, property and attributehtml have the following code: <input id = "in_1" value = "1" Something = "whatever"> Create an input field on the html page (note that a DOM is added to this label. does not exist "), execute the following statement var in1 = document in JS. getElementById ('in _ 1'); execute the console statement. log (in1); from the printed result on the console, we can see that in1 contains an attribute named "attributes". Its type is NamedNodeMap, there are also two basic attributes: "id" and "value", but there is no custom attribute "something.

attributes: NamedNodeMapvalue: "1"id: "in_1"

 

Some consoles may not print properties on in1, so you can run the following command to print the properties to be observed:
console.log(in1.id); // 'in_1'console.log(in1.value); // 1console.log(in1.sth); // undefined

 

It can be found that only "id" and "value" of the three attributes in the tag will be created on in1, and "something" will not be created. This is because every DOM object has its default basic attributes, and at the time of creation, it only creates these basic attributes, the Custom Attributes in TAG tags are not directly stored in the DOM. We perform an additional test, create another input tag, and perform similar operations:
Html: <input id = "in_2"> JS: var in2 = document. getElementById ('in _ 2'); console. log (in2); from the print information, we can see: id: "in_2" value: null

 

Although "value" is not defined in the TAG, because it is the default basic attribute of DOM, it will still be created during DOM initialization. From this we can conclude that DOM has its default basic attributes, which are called "property". In any case, they will be created on the DOM object during initialization. If you assign values to these attributes in the TAG, these values will be assigned to the DOM property with the same name as the initial value. Now back to the first input ("# in_1"), we will ask, where did "something" go? Don't worry. Let's print out the attributes attribute to see the console. log (in2); there are several attributes: 0: id1: value2: sthlength: 3 _ proto __: NamedNodeMap the original "something" is placed in the attributes object, this object records the number of attributes defined in the TAG in order. At this time, if you print out the attributes of the second input tag, you will find that there is only one "id" attribute, and "length" is 1. It can be seen from this that attributes is a subset of property and stores the attributes defined on HTML tags. If we further explore every attribute in attitudes, we will find that they are not simple objects. They are Attr objects and have NodeType, NodeName, and other attributes. I will study this point later. Note: printing attribute does not directly obtain the object value, but a string containing the attribute name and value, such as console. log (in1.attibutes. something); // 'something = "whatever" ': the attributes and values defined in the HTML Tag will be saved in the attributes attribute of the DOM object; the type in JavaScript of these attribute attributes is Attr, not just to save the attribute name and value. What will happen if we change the property and attribute values? Execute the following statement:
in1.value = 'new value of prop';console.log(in1.value); // 'new value of prop'console.log(in1.attributes.value); // 'value="1"'

 

At this time, the value in the input column on the page is changed to "new value of prop", and the value in propety is also changed to a new value, but attributes is still "1 ". It can be inferred from this that the values of attributes with the same name are not two-way bound. If the value in attitudes is set in turn, what will happen? In1.attributes. value. value = 'new value of attr'; console. log (in1.value); // 'new value of attr' console. log (in1.attributes. value); // 'new value of attr 'at this time, the input column on the page is updated, and the value in the property is also changed. In addition, execute the following statement to obtain the same result: in1.attributes. value. nodeValue = 'new value of attr '; from this, we can conclude that the property can be synchronized from the attribute; the attribute will not synchronize the value on the property; data Binding between attribute and property is unidirectional. attribute-> property; changing any value of property and attribute reflects the update to the HTML page; how does the attr and prop methods in jQuery analyze attribute and property based on jQuery? First, use jQuery. prop to test
$(in1).prop('value', 'new prop form $');console.log(in1.value); // 'new prop form $'console.log(in1.attributes.value); // '1'

 

The value in the input column is updated, but the attribute is not updated. Then use jQuery. attr to test
$(in1).attr('value', 'new attr form $');console.log(in1.value); // 'new attr form $'console.log(in1.attributes.value); // 'new attr form $'

 

The value in the input column is updated, and both property and attribute are updated. From the above test, we can infer that jQuery. attr and jQuery. the effect of prop is basically the same as that of the native operation method. The property will get the synchronization from the attribute, but the attribute will not get the synchronization from the property. So how is jQuery implemented? Next, let's take a look at the source code of jQuery. attr and jQuery. prop.
JQuery source code $ (). prop source code jQuery. fn. extend ({prop: function (name, value) {return access (this, jQuery. prop, name, value, arguments. length> 1 );},... // removeProp method}); $ (). attr source code jQuery. fn. extend ({attr: function (name, value) {return access (this, jQuery. attr, name, value, arguments. length> 1 );},... // removeAttr method}); whether it is attr or prop, the access method is called to access the elements of the DOM object. Therefore, we need to find more information, you must read the access implementation source code. JQuery. access // This is a multi-function that can be used to obtain or set the value of a set // if this "value" is a function, then this function will be executed // @ param elems, Element Set // @ param fn, method for processing the element // @ param key, element name // @ param value, new Value // @ param chainable, whether to perform chained call // @ param emptyGet, // @ param raw, whether the element is a non-function object var access = jQuery. access = function (elems, fn, key, value, chainable, emptyGet, raw) {var I = 0, // iteration count length = elems. length, // element length bulk = key = null; // determines whether a specific key exists. (Attribute name) // if multiple attributes exist, recursively call them to access these values one by one if (jQuery. type (key) = "object") {chainable = true; for (I in key) {jQuery. access (elems, fn, I, key [I], true, emptyGet, raw);} // set a value} else if (value! = Undefined) {chainable = true; if (! JQuery. isFunction (value) {// if the value is not a functionraw = true;} if (bulk) {// Bulk operations run against the entire set // if the attribute name is empty and the attribute name is not a function, use the external processing method fn and value to perform the operation if (raw) {fn. call (elems, value); fn = null ;//... when t when executing function values // If value is a function, then re-construct the processing method fn // This new fn will pass the value function as the callback function to the old processing method} else {bulk = fn; fn = function (elem, key, value) {return bulk. cal L (jQuery (elem), value) ;}}} if (fn) {// use the processing method fn to process each element in the element set for (; I <length; I ++) {fn (elems [I], key, raw? Value: value. call (elems [I], I, fn (elems [I], key); // if the value is a funciton, then, use this function to return a value and pass in fn }}return chainable? Elems: // if it is a chained call, the returned Element Set // Getsbulk? Fn. call (elems): length? Fn (elems [0], key): emptyGet ;};

 

Although the access method is not long, it is very difficult to understand it completely. Therefore, you can simplify access by calling jQuery. fn. attr. JQuery. fn. attr/jQuery. fn. the access Call in prop $ (). call method of attr: $ (). attr (propertyName) // obtain a single attribute $ (). attr (propertyName, value) // sets a single attribute $ (). attr (properties) // set multiple attributes $ (). attr (propertyName, function) // calls the callback function prop in the same way as attr, and will not be repeated here. For the sake of simplicity, only the first and second call methods are studied here. Call Statement:
Access (this, jQuery. attr, name, value, arguments. length> 1); simplified access: // The current jQuery object of elems, which may contain multiple DOM objects // fn jQuery. attr method // name attribute name // value of the value Attribute // chainable if the value is null, chainable is false; otherwise, chainable is truevar access = jQuery. access = function (elems, fn, key, value, chainable, emptyGet, raw) {var I = 0, // iteration count length = elems. length, // attribute quantity bulk = false; // key! = Nullif (value! = Undefined) {// if the value is not empty, set a new value; otherwise, return the value chainable = true; raw = true; // value is not functionif (fn) {// fn is jQuery. attrfor (; I <length; I ++) {fn (elems [I], key, value); // jQuery. attr (elems, key, value) ;}} if (chainable) {// value is not empty, it indicates getreturn elems; // return element implementation chained call} else {if (length) {// if the length of the element set is not zero, return the attribute value of the first element return fn (elems [0], key); // jQuery. attr (elems [0], key) ;}else {return emptyGet; // return a default value, which is undefined }}};

 

By simplifying the code, we can know that access is used to traverse the element set obtained by the previous $ call and call the fn function for it. In jQuery. attr and jQuery. prop, access is used to traverse element sets and merge them to control attribute and property. The access source code contains multiple conditional transfer codes, which are dazzled. The ultimate goal is to implement the variables of element sets and perform different operations, complex Code simplifies jQuery interfaces and greatly improves code reusability. This means that the amount of code is reduced and the code density is increased, reducing the JS file size. These are all off-questions. Now we return to the implementation of $ (). attr and $ (). prop. In general, both prototype methods use access to variable element sets and call jQuery. prop and jQuery. attr methods for each element. Note that jQuery. prop and jQuery. attr is not a method on the prototype chain, but a method of the jQuery object. It uses jQuery. extend (jQuery. fn. prop and jQuery. fn. attr uses jQuery. fn. extend ). Let's take a look at the source code of these two methods.
JQury. attrjQuery. extend ({attr: function (elem, name, value) {var hooks, ret, nType = elem. nodeType; // get Node type // If elem is empty or NodeType is of the following type // 2: Attr, attribute, subnode has Text, EntityReference // 3: Text, text Content in the element or attribute // 8: Comment, Comment // do not perform any operation if (! Elem | nType = 3 | nType = 8 | nType = 2) {return ;}// if the attitude method is supported, call the property method if (typeof elem. getAttribute === strundefined) {return jQuery. prop (elem, name, value);} // if the Node type of elem is not element (1) if (nType! = 1 |! JQuery. isXMLDoc (elem) {name = name. toLowerCase (); // For browser compatibility, obtain the hook function and process some special elements like hooks = jQuery. attrHooks [name] | (jQuery. expr. match. bool. test (name )? BoolHook: nodeHook);} if (value! = Undefined) {// if the value is not undefined, execute "SET" if (value = null) {// if the value is null, remove attributejQuery. removeAttr (elem, name);} else if (hooks & "set" in hooks & (ret = hooks. set (elem, value, name ))! = Undefined) {return ret; // use the hook function} else {// use the setAttribute method of Dom elem. setAttribute (name, value + ""); // Note: convert value to string because all attribute values are stringreturn value;} // If value is undefined, run "GET"} else if (hooks & "get" in hooks & (ret = hooks. get (elem, name ))! = Null) {return ret; // use the hook function} else {ret = jQuery. find. attr (elem, name); // actually called Sizzle. attr. This method is used to solve compatibility issues to obtain the attribute value // return the obtained value return ret = null? Undefined: ret ;}},...});

 

The Code shows that jQuery. attr calls the getAttribute and setAttribute methods.
JQeury. propjQuery. extend ({... prop: function (elem, name, value) {var ret, hooks, notxml, nType = elem. nodeType; // filter comments, Attr, element text content if (! Elem | nType = 3 | nType = 8 | nType = 2) {return;} notxml = nType! = 1 |! JQuery. isXMLDoc (elem); if (notxml) {// if not the element name = jQuery. propFix [name] | name; // corrected the property name hooks = jQuery. propHooks [name]; // obtain the hook function} if (value! = Undefined) {// execute "SET" return hooks & "set" in hooks & (ret = hooks. set (elem, value, name ))! = Undefined? Ret: // call the hook function (elem [name] = value ); // assign a value directly to elem [name]} else {// execute "GET" return hooks & "get" in hooks & (ret = hooks. get (elem, name ))! = Null? Ret: // call the hook function elem [name]; // directly return elem [name] }},...});

 

JQuery. prop directly performs operations on the property on the DOM object. By comparing jQuery. prop and jQuery. attr, we can find that the former performs operations on the property of the DOM object directly, while the latter calls the setAttribute and getAttribute methods. What are the setAttribute and getAttribute methods? What is the effect? Based on the input boxes used in the previous test, setAttribute and getAttribute run the following code:
In1.setAttribute ('value', 'new attr from setattribute'); console. log (in1.getAttribute ('value'); // 'new attr from setattribute' console. log (in1.value); // 'new attr from setattribute' console. log (in1.attributes. value); // 'value = "new attr from setAttribute" ', which is actually an Attr object

 

After the setAttribute is executed, it is like directly modifying the attributes of the same name in attributes; The getAttribute result is the same as the result of accessing the property, rather than returning an Attr object as the result of directly accessing the attritudes. In a special example, href. However, do all tags and attributes maintain this feature? Next, let's take a look at the href attribute/feature. First, create a tag in html: <a hrefw.'page_1.html 'id = 'A _ 1'> </a> execute the following code in the JS Script: console. log (a1.href); // 'file: // D:/GitHub/JS/html/test_01/page_1.html 'console. log (a1.getAttribute ('href '); // 'page_1.html' you can see that the absolute path is saved in property, while the relative path is saved in attribute. So what happens if these values are changed? Change attribute:
A1.setAttribute ('href ', 'page_2.html'); // relative path console. log (a1.href); // 'file: // D:/GitHub/JS/html/test_01/page_2.html 'console. log (a1.getAttribute ('href '); // 'page_2.html' a1. setAttribute ('href ','/page_3.html '); // the root directory path is console. log (a1.href); // 'file: // D:/page_3.html 'console. log (a1.getAttribute ('href '); //'/page_3.html 'change property: a1.href = 'home.html'; // relative path console. log (a1.href); // 'file: // D:/GitHub/JS/html/test_01/home.html 'console. log (a1.getAttribute ('href '); // 'home.html' a1. href = '/home.html'; // the root directory path is console. log (a1.href); // 'file: // D:/home.html 'console. log (a1.getAttribute ('href '); //'/home.html'

 

From this point, we can find that href is a special property/feature, and the two are two-way binding. Changing either side will change the value of the other side. Furthermore, this is not a simple two-way binding. The href in property always saves the absolute path, while the href in attribute stores the relative path. Here, the difference between attribute and property is a little more, but this makes people more confused. Are there other similar special examples? Id:
a1.id = 'new_id';console.log(a1.id); // 'new_id'console.log(a1.getAttribute('id')); // 'new_id'

 

Today, the id in attribute is synchronized from the id in property, and the data direction is changed to property <=> attribute; disabled. Let's take a look at the disabled attribute, we add the "disabled" feature to the first one: <input id = "in_1" value = "1" Something = "whatever" disabled = 'Disabled '> // at this time, the input has been disabled and the following code is executed:
Console. log (in1.disabled); // truein1.setAttribute ('Disabled ', false); // set disabled in attribute. The console is not disabled whether it is false or null. log (in1); // trueconsole. log (in1.getAttribute ('Disabled '); // 'false'

 

Changing the disabled in attributes does not change the property or cancel the disabled Effect in the input column. If you change it to the following code:
Console. log (in1.disabled); // truein1.disabled = false; // Disable console. log (in1.disabled); // falseconsole. log (in1.getAttribute ('Disabled '); // null, the disabled attribute has been removed

 

Or: console. log (in1.disabled); // truein1.removeAttribute ('Disabled '); // remove the disabled attribute to disable the console. log (in1.disabled); // falseconsole. log (in1.getAttribute ('Disabled '); // null, the disabled in attribute has been removed and you can find that setting the disabled in property to false will remove the disabled in attributes. In this way, Data Binding becomes property <=> attribute; therefore, the Data Binding problem between property and attritude cannot be simply described as "property <-attribute. After summing up and analyzing so much, we have a deeper understanding of the difference between property and attribute. Here, we will summarize that the default basic property will be created during DOM object initialization; only attributes defined in HTML tags are saved in the attributes attribute of property. attributes initialize attributes of the same name in property, but custom attributes do not appear in property; attribute values are all strings. Data bound to attributes is synchronized to property, but property changes do not change attribute. For attributes such as value and class, the Data Binding direction is unidirectional. attribute-> property; for id, data binding is bidirectional. attribute <=> property; for disabled, if the value of disabled on property is false Disabled will certainly exist. In this case, data binding can be considered as bidirectional. You can use the setAttribute method of DOM to change attribute at the same time. directly accessing the value on attributes will get an Attr object, the value of attribute is directly obtained through the getAttribute method. In most cases (unless there is a browser compatibility problem), jQuery. attr is implemented through setAttribute, while jQuery. prop will directly access the property of the DOM object. So far, it is concluded that property is the property of the DOM object itself, attribute is a feature that we assign to it by setting HTML tags. attribute and property attributes with the same name may have some special data relationships, these connections are different for different attributes/features. In fact, it is difficult to describe the differences and links between property and attribute here with simple technical features. I found the following answer on StackFlow, or it will be closer to the real answer: these words existed way before Computer Science came around. attribute is a quality or object that we attribute to someone or something. for example, the scepter is an attribute of power and statehood. property is a quality that exists without any attribution. for example, clay has adhesive qualities; or, one of the properties of metals is electrical conductivity. properties demonstrate themselves though physical phenomena without the need attribute them to someone or something. by the same token, saying that someone has masculine attributes is self-evident. in effect, you cocould say that a property is owned by someone or something. to be fair though, in Computer Science these two words, at least for the most part, can be used interchangeably-but then again programmers usually don't hold degrees in English Literature and do not write or care much about grammar books :).

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.