最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Why can you chain some JavaScript methods but not others? - Stack Overflow

programmeradmin1浏览0评论

I'm relatively new to JavaScript and I would like to know when it is okay to chain JavaScript methods and when not, and what is the reason when you can't....

I'm creating an element and want to assign a class-name and then put some text inside the element. But for some reason you can't chain these methods. Ideally I would do something like this:

var li = document.createElement("li").classList.add("className").innerHTML = "Some string";

I kind of understand why you can't chain the final part, because you can't assign twice. But I can't even chain the second method, instead I have to do this:

var li = document.createElement("li");
li.classList.add("className");
li.innerHTML = "Some string";

Why is that?

I'm relatively new to JavaScript and I would like to know when it is okay to chain JavaScript methods and when not, and what is the reason when you can't....

I'm creating an element and want to assign a class-name and then put some text inside the element. But for some reason you can't chain these methods. Ideally I would do something like this:

var li = document.createElement("li").classList.add("className").innerHTML = "Some string";

I kind of understand why you can't chain the final part, because you can't assign twice. But I can't even chain the second method, instead I have to do this:

var li = document.createElement("li");
li.classList.add("className");
li.innerHTML = "Some string";

Why is that?

Share Improve this question asked Nov 3, 2016 at 11:03 AndrewRMillarAndrewRMillar 6621 gold badge7 silver badges21 bronze badges 1
  • If the later method can be applied on the return type of the first method then you can chain the methods, otherwise not. – void Commented Nov 3, 2016 at 11:05
Add a ment  | 

5 Answers 5

Reset to default 3

Chaining isn't anything special. It's just using the return value of a function. If a function returns an object that has a method on it, then you can use that method by calling it directly on the result of calling the function. That is,

foo().bar();

...works if foo returns an object that has a method called bar.

You can't do what you've shown in your first code block because:

  • add doesn't return anything, so the result of calling it is undefined.
  • If add did return something, it almost certainly wouldn't be the element createElement created. (It probably should return a reference to the DOMTokenList you called it on, but it doesn't.)
  • And even if it did, the result of an assignment operation (innerHTML = ...) is the value that was assigned, not a reference to the element.

Side note: If you like chaining APIs, look at using jQuery. It lets you do this:

var li = $("<li>").addClass("className").html("Some string");

...because most of its API methods return the jQuery instance that they were called on or another useful jQuery instance if not (and $() returns the set containing the single element outermost element it creates in the $("<li>") example). The API is specifically designed with chaining in mind. The DOM API is not.

It depends on the return value of the function. In your case the li.classList is an attribute, not a function returning the method itself. Thus you cannot chain it.

Chaining depends on return type of called function

document.createElement("li")

will return a HTML element which has property called classList

.classList will return a DOMTokenList. This in turn has property .add. But .add does not return anything. Hence you cannot call .innerHTML

document.createElement("li").classList.add("className").innerHTML = "Some string";

Sample

var element = document.createElement("li");
console.log(element)

var classList = element.classList
console.log(classList)

var add = classList.add('dummy');
console.log(add)

In order to use chaining the last method must return a value. If you want to create an instance of an object, every method must return the this object.

var Dog= function() {
  this.name = 'Buck';
  this.color = 'brown';
};

Dog.prototype.setName = function(name) {
  this.name = name;
  return this;
};

Dog.prototype.setColor = function(color) {
  this.color = color;
  return this;
};

So with chaining it will look like this

new Dog()
  .setName('Bob')
  .setColor('black')

li.classList.add("className"); this line doesn't return an object (a result of li.classList or simply li for instance), instead it returns undefined as per this doc: http://www.javascripture./DOMTokenList . Thus, you cannot call any methods on the result.

发布评论

评论列表(0)

  1. 暂无评论