A detailed explanation of the difference between property and Attribute in JavaScript

Source: Internet
Author: User



Property and attribute are very easy to confuse, and the Chinese translation of two words is very similar (properties: attributes, Attribute: properties), but in fact, they are different things and belong to different categories.



Property is an attribute in the DOM and is the object in JavaScript;



attribute is the attribute on the HTML tag, and its value can only be a string;


Analyze property and attribute based on JavaScript


There is a piece of code in the HTML:


<input id= "in_1" value= "1" sth= "whatever" >


Simply create an input field on the HTML page (note that a non-existent attribute "STH" in the DOM is added to this tab), at which point the following statement is executed in JS


var in1 = document.getElementById (' in_1 ');


EXECUTE statement


Console.log (in1);


From the console print results, you can see that in1 contains a property named "Attributes", its type is namednodemap, and there are "id" and "value" two basic properties, but there is no "sth" this custom property.


Attributes:namednodemapvalue: "1" ID: "In_1"


Some console may not print properties on in1, so you can print the properties you want to observe by executing the following command:


Console.log (in1.id);//' In_1 ' Console.log (in1.value);//1console.log (IN1.STH);//undefined


You can see that the three attributes in the tag, only "id" and "value" are created on in1, and "Sth" is not created. This is because every DOM object has its default base property, and when it is created, it only creates these basic properties, and the properties we customize in the tag tag are not placed directly in the DOM .



Let's do an extra test, create another input tag, and do something like this:



Html:


<input id= "In_2" >


Js:


var in2 = document.getElementById (' in_2 '); Console.log (in2);


From the printing information, you can see:


ID: "In_2" Value:null


Although we do not define "value" in the tag, it is still created when the DOM is initialized because it is the default basic property of the DOM. From this we can draw the conclusion that:


    • The DOM has its default basic properties, which are called "property" , however, they will be created on the DOM object at initialization time.
    • If these properties are assigned at tag, then these values are assigned to the DOM's property with the same name as the initial value.


Now go back to the first input ("#in_1") and we'll ask, "Where's sth?" Don't worry, we'll print out the attributes attribute to see


Console.log (in2);


There are several properties above:


0:ID1:VALUE2:STHLENGTH:3__PROTO__: NamedNodeMap


The original "Sth" was put into the object of attributes, the object in order to record the number of attributes and attributes we have defined in the tag. At this point, if you print the attributes of the second input tag again, you will find that there is only one "id" attribute and "Length" is 1.



As can be seen from here,attributes is a subset of the property, which holds the attributes defined on the HTML tag. If you explore each of the properties in attitudes, you will find that they are not simple objects, they are objects of a attr type, and have properties such as NodeType, NodeName, and so on. On this point, we will look at it later. Note that the Print attribute property does not directly get the value of the object, but instead gets a string that contains the property name and value , such as:


Console.log (in1.attibutes.sth);//' sth= "whatever" '


From this we can conclude that:


    • H The properties and values defined in the tml tag save the Attributes property of the DOM object. ;
    • The types in JavaScript for these attribute properties are attr, rather than just saving property names and values so easily;


So what happens if we change the value of the property and attribute? 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 point, the value of the input field in the page becomes "new value of Prop", and value in Propety becomes a new value, but attributes is still "1". From here, it can be inferred that the property and attribute values of the same name attribute are not two-way bound.



If in turn, set the value in attitudes, what will the effect be?


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 point, the input field in the page is updated and the value in the property has changed. Also, execute the following statement to get the same result


In1.attributes.value.nodeValue = ' new value of attr ';


Thus, it can be concluded that:


    • The property can be synchronized from the attribute ;
    • attribute does not synchronize the value on the property;
    • data binding between attribute and property is one-way, Attribute->property;
    • Changing any value on the property and attribute will reflect the update to the HTML page;
Analysis of attribute and property based on jquery


So what are the attr and prop methods in 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 of the input field was updated, but attribute was not updated.



and test it with jquery.attr.


$ (in1). attr (' value ', ' New attr form $ '); Console.log (in1.value);//' New attr form $ ' console.log (in1.attributes.value); /' New attr form $ '


The value of the input field is updated, and both the property and the attribute are updated.



From the phenomena described above, it can be inferred that the jquery.attr and Jquery.prop are essentially the same as the native operating methods, the propertygets the synchronization from the attribute, but attribute does not get the synchronization from the property . So how does jquery work?



Next, let's look at the source code of JQUERY.ATTR and Jquery.prop.


jquery source $ (). 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
});


Either attr or prop, the access method is called to access the elements of the DOM object, so to study more, you have to read access's implementation source.


Jquery.access
// This is a versatile function that can be used to get or set the value of a collection
// If this "value" is a function, then this function will be executed

// @param elems, element collection
// @param fn, method for processing elements
// @param key, element name
// @param value, new value
// @param chainable, whether to make chained calls
// @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; // determine if there is a specific key (attribute name)

// if there are multiple attributes, call recursively 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 value is not a function
raw = true;
}

if (bulk) {
// Bulk operations run against the entire set
// If the attribute name is empty and the attribute name is not a function, the external processing methods fn and value are used to perform the operation
if (raw) {
fn.call (elems, value);
fn = null;

// ... except when executing function values
// If value is a function, then reconstruct the processing method fn
// This new fn will pass the value function as a callback function to the old processing method
} else {
bulk = fn;
fn = function (elem, key, value) {
return bulk.call (jQuery (elem), value);
};
}
}

if (fn) {// use 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 value is a funciton, first use this function to return a value and pass in fn
}
}
}

return chainable?
elems: // if the call is chained, return the element collection

// Gets
bulk?
fn.call (elems):
length? fn (elems [0], key): emptyGet;
};


Although the access method is not long, but is very round, it is not easy to read it completely, so you can simplify access for jQuery.fn.attr calls.


The access call in Jquery.fn.attr/jquery.fn.prop


$ (). Attr Method of invocation:


    • $ (). attr (PropertyName)//Get a single property
    • $ (). attr (propertyname, value)//Set individual properties
    • $ (). attr (properties)//Set multiple attributes
    • $ (). attr (propertyname, function)//Call callback function on property


Prop is called in the same way as attr, and is not repeated here. For the sake of simplicity, only the first and second invocation methods are studied here.



Call statement:


Access (this, jquery.attr, name, value, Arguments.length > 1);


Simplified access:


// elems the current jQuery object, which may contain multiple DOM objects
// fn jQuery.attr method
// name attribute name
// value of the value attribute
// chainable if value is empty, then chainable is false, otherwise chainable is true

var access = jQuery.access = function (elems, fn, key, value, chainable, emptyGet, raw) {

var i = 0, // iteration count
length = elems.length, // number of attributes
bulk = false; // key! = null

if (value! == undefined) {// If value is not empty, set a new value, otherwise return the value of the property
chainable = true;
raw = true; // value is not a function

if (fn) {// fn is jQuery.attr
for (; i <length; i ++) {
fn (elems [i], key, value); // jQuery.attr (elems, key, value);
}
}
}

if (chainable) {// value is not empty, it means get
return elems; // implement chained call to return elements
} else {
if (length) {// If the element collection length is not zero, return the attribute value of the first element
return fn (elems [0], key); // jQuery.attr (elems [0], key);
} else {
return emptyGet; // returns a default value, here is undefined
}
}
};


By simplifying the code, you know that access is the function of iterating through the collection of elements from the last $ call and calling the FN function on it. Inside Jquery.attr and Jquery.prop, access is used to traverse the element set merging to control its implementation of attribute and property. Access in the source code, there are multiple sections of conditional transfer codes, look dazzling, the ultimate goal is to be able to implement the elements set of variables and do different operations, complex code to make jquery interface more simple, can greatly improve the code reusability, meaning to reduce the amount of code, Increase the density of the code so that the JS file size is reduced.



These are off-topic, now go back to $ (). attr and $ (). Prop implementation. In general, both of these prototype methods use access to make variables for the set of elements and invoke the Jquery.prop and jquery.attr methods on each element. Be aware that The Jquery.prop and jquery.attr here are not methods on the prototype chain, but the method of the object itself, which is extended using the Jquery.extend method (JQuery.fn.prop and jQuery.fn.attr are used Jquery.fn . Extend for method expansion).



Look at the source code of the two methods below.


Jqury.attr
jQuery.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 element
name = jQuery.propFix [name] || name; // fix property name
hooks = jQuery.propHooks [name]; // Get hook functions
}

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); // directly assign a value to elem [name]

} else {// execute "GET"
return hooks && "get" in hooks && (ret = hooks.get (elem, name))! == null?
ret: // call the hook function
elem [name]; // return elem [name] directly
}
},

...
});


As you can see from the code, JQUERY.ATTR calls the GetAttribute and SetAttribute methods.


Jqeury.prop
jQuery.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 element
name = jQuery.propFix [name] || name; // fix property name
hooks = jQuery.propHooks [name]; // Get hook functions
}

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); // directly assign a value to elem [name]

} else {// execute "GET"
return hooks && "get" in hooks && (ret = hooks.get (elem, name))! == null?
ret: // call the hook function
elem [name]; // return elem [name] directly
}
},

...
});


The Jquery.prop is directly manipulating the property on the DOM object.



By comparing Jquery.prop and jquery.attr, it is found that the former directly operates on the property of the DOM object and the latter calls the SetAttribute and GetAttribute methods. What is the method of setattribute and getattribute? What's the effect?


SetAttribute and GetAttribute


Based on the input box used in the previous test, execute 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 SetAttribute is executed, it is as if the property of the same name is changed directly in attributes ;
The result of GetAttribute is the same as the result of accessing the property, rather than returning a attr object as if it were accessed directly by Attritudes.


Special examples of href


However, is not all tags, all attributes maintained such a feature? Let's look at the href attribute/attribute.



First create a tag in HTML:


<a href= ' 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 '


As you can see, the property holds an absolute path, whereas a relative path is saved in attribute. So, what happens if you change these values?



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’); // root directory path
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’; // root directory path
console.log (a1.href); // ‘file: /// D: /home.html’
console.log (a1.getAttribute (‘href‘)); // ‘/home.html’


It can be found from here that href is a special attribute/attribute, which is two-way bound, and changing either side will cause the value of the other party to change. Moreover, this is not a simple two-way binding, and the href in the property always holds the absolute path, while the href in attribute is the relative path.



Seeing here, the difference between attribute and property is a little bit more, however, it makes people more puzzled. Are there other similar special cases?


Id


Try to change the ID in the property:


a1.id = ‘new_id‘;
console.log(a1.id);						// ‘new_id‘
console.log(a1.getAttribute(‘id‘));		// ‘new_id‘


God, now attribute in the ID from the property of the ID has been synchronized, the data direction into the property <=> attribute;


Disabled


Take a look at the disabled attribute, we add the "disabled" feature to the first:


<input id= "in_1" value= "1" sth= "whatever" disabled= ' disabled ' >//this time input has been disabled


Then execute the following code:


console.log (in1.disabled); // true
in1.setAttribute (‘disabled’, false); // Set disabled in attribute, whether it is false or null will not be disabled
console.log (in1); // true
console.log (in1.getAttribute (‘disabled‘)); // ‘false’


Changing the disabled in attributes does not change the property, nor does it cancel the disable effect of the input bar.



If you change to the following code:


console.log (in1.disabled); // true
in1.disabled = false; // cancel disabled
console.log (in1.disabled); // false
console.log (in1.getAttribute (‘disabled’)); // null, disabled in attribute has been removed


Or:


console.log (in1.disabled); // true
in1.removeAttribute (‘disabled’); // remove disabled on attribute to cancel disable
console.log (in1.disabled); // false
console.log (in1.getAttribute (‘disabled’)); // null, disabled in attribute has been removed


You can see that setting the disabled in the property to False will remove the disabled in attributes. This data binding becomes again,Property<=>attribute;



So the problem of data binding between property and Attritude cannot be simply explained by "Property<-attribute".


Summarize


Analysis of so much, the difference between the property and attribute understanding is also deeper, summed up here:


Create
    • The default base property is created when the DOM object is initialized;
    • Only the attribute defined in the HTML tag will be stored in the property's attributes attribute;
    • Attribute initializes the property with the same name, but the custom attribute does not appear in the properties;
    • The values of the attribute are all strings ;
Data binding
    • Attributes data will be synchronized to the property, but the property changes will not change the attribute;
    • For attributes/attributes such as Value,class, the direction of data binding is unidirectional,attribute->property;
    • For the ID , data binding is bidirectional,attribute<=>property;
    • For disabled, the disabled on the property is false, and the disabled on the attribute is bound to exist, at which point the data binding can be considered bidirectional ;
Use
    • You can use the DOM's SetAttribute method to change the attribute at the same time;
    • Direct access to the value on the attributes will get a attr object, and access through the GetAttribute method will directly get the value of attribute;
    • In most cases (unless there is a browser compatibility issue), Jquery.attr is implemented through setattribute, and Jquery.prop directly accesses the property of the DOM object;


Up to this point, the property is an attribute owned by the DOM object itself, and attribute is the attribute that we assign to it by setting the HTML tag, and there are special data links between the properties/attributes of the attribute and the property that have the same name. These connections differ in different attributes/attributes.



In fact, here, the difference between property and attribute is difficult to describe with simple technical features, and I find the following answer on Stackflow, or closer to the real answer:


These words existed before computer science came around.

Attribute is a quality or object, we Attribute to someone or something. For example, the scepter are an attribute of power and statehood.

Property was a quality that exists without any attribution. For example, clay have 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 tokens, saying that someone have masculine attributes is self-evident. In the effect, you could say, the A property was owned by someone or something.

To is fair though, in computer science These-words, at least for the more part, can is used interchangeably–but then Again programmers usually don ' t hold degrees in 中文版 literature and do not write or care much about grammar books
.


The two most critical words:


    • attribute is a trait or object that we give to something.
    • Property (attribute) is a trait that has long existed and does not require external attribution.
(The above content is for reference only)reprint: http://www.codeceo.com/article/javascript-property-attribute.html


A detailed explanation of the difference between property and Attribute in JavaScript


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.