简体   繁体   English

JavaScript中的str.fun()/ str.fun / fun(str)有什么区别?

[英]What's the difference between str.fun() / str.fun / fun(str) in JavaScript?

I tried googling but couldn't find a precise answer, so allow me to try and ask here. 我尝试使用Google搜索,但找不到精确的答案,因此请允许我在这里尝试提问。 If the question does not seem proper, please let me know and I'll delete it. 如果问题似乎不正确,请让我知道,我将其删除。

In JS you've got three different way of writing certain build in functionalities: 在JS中,您可以通过三种不同的方式来编写某些内部功能:

  • str.length str.length
  • str.toString() str.toString()
  • parseInt(str) parseInt函数(STR)

I wonder if there is a reason behind these different ways of writing. 我想知道这些不同的写作方式背后是否有原因。 As a new user I don't grasp why it couldn't be streamlined as: length(str) / toString(str) / parseInt(str) or with dot formulation. 作为新用户,我不明白为什么不能将其简化为:length(str)/ toString(str)/ parseInt(str)或使用点表示法。

I however think if I do know the reason behind these differences, it would give me a better understanding of JavaScript. 但是,我认为,如果我确实知道这些差异背后的原因,那将使我对JavaScript有更好的了解。

Length is one of the attributes of string in JavaScript. 长度是JavaScript中字符串的属性之一。 Hence you use string.length to get the length of the string. 因此,您可以使用string.length来获取字符串的长度。 toString is a function for string objects, hence we use stringobj.toString(). toString是用于字符串对象的函数,因此我们使用stringobj.toString()。 parsInt(str) is a global function which takes string as a parameter. parsInt(str)是一个以字符串为参数的全局函数。

JavaScript is object-oriented, so there are functions or procedures which require first an object to use as this in their bodies. JavaScript是面向对象的,所以有这首先需要一个对象作为使用的功能或程序this在他们的身体。 str.length is a property, both syntactically and semantically. str.length在语法和语义上都是一个属性。 It doesn't require any parameters and represents some quality of the object. 它不需要任何参数,并表示对象的某种质量。 obj.toString() is a method (a function attached to an object), which doesn't represent any characteristics of the object, but rather operates on its state, computes some new values, or changes the state of the object a lot. obj.toString()是一种方法(附加到对象的函数),它不代表对象的任何特征,而是根据其状态进行操作,计算一些新值或对对象的状态进行很多更改。 parseInt(str) is a "global" function, which represents an operation not attached to any type or object. parseInt(str)是“全局”函数,表示未附加到任何类型或对象的操作。

Under the hood, these three ways may be well implemented with just calling a function, passing this as the first parameter (like C# does, for example). 在后台,只需调用一个函数并将this作为第一个参数传递(例如,像C#一样),就可以很好地实现这三种方式。 The semantic difference is the important one. 语义上的差异是重要的。

So why not use just the third syntax, like for example PHP does? 那么,为什么不只使用第三个语法,例如PHP呢? First, it doesn't bloat the global environment with lots of functions which only work for one specific case and type, allowing you to specify any new function you want without breaking the old functionality. 首先,它不会用仅适用于一种特定情况和类型的许多功能在全局环境中肿,允许您在不破坏旧功能的情况下指定所需的任何新功能。 Second, it ecourages you to use object-oriented concepts, because you can already see working objects and methods in the language, and can try to make something similar. 其次,它鼓励您使用面向对象的概念,因为您已经可以用该语言查看有效的对象和方法,并且可以尝试做类似的事情。

And why isn't parseInt a method? 为什么不使用parseInt方法呢? It can as well be str.toInt() without any issues, it's just the way JavaScript designers wanted it to be, although it seems also a bit logical to me to make it a static method Number.parseInt(str) , because the behaviour of the function is relevant more to the Number type than the String type. 它也可以是str.toInt()没有任何问题,这只是JavaScript设计人员想要的方式,尽管对我来说,使其成为静态方法Number.parseInt(str)似乎也合乎逻辑,函数的功能与数字类型的相关性大于字符串类型。

Behaviour of these expressions is defined in ECMAScript grammar. 这些表达式的行为在ECMAScript语法中定义。 You could read the specification to understand it thoroughly: ECMAScript2015 specification . 可以阅读规范以全面了解它: ECMAScript2015规范 However, as pointed out by Bergi, it's probably not the best resource for beginners because it doesn't explain anything, it just states how things are. 但是,正如Bergi所指出的那样,对于初学者来说,它可能不是最佳的资源,因为它没有解释任何内容,而只是说明事情的发展。 Moreover I think it might be too difficult for you to be able to grasp concepts described in this specification because of the very formal language used. 此外,由于使用了非常正式的语言,我认为您可能很难掌握本规范中描述的概念。

Therefore I recommend to start with something way simpler, such as a very basic introduction to JavaScript: JavaScript Basics on MDN . 因此,我建议从更简单的方式开始,例如对JavaScript进行非常基本的介绍: MDN上的JavaScript基础 MDN is a great resource. MDN是一个很好的资源。

But to answer your question just briefly: 但是,只需简短地回答您的问题:

  • str.length is accessing a property of the str object. str.length正在访问str对象的属性。
  • parseInt(str) is a function call parseInt(str)是一个函数调用
  • str.toString() is a call of a function which is a property of the str object. str.toString()是对函数的调用,该函数是str对象的属性。 Such functions are usually named methods . 这些函数通常称为方法

Functions and methods are in fact very similar but one of the differences (except for the obvious syntax difference) is that methods by default have context ( this ) set to refer to the object which they're part of. 函数和方法实际上非常相似,但是区别之一(明显的语法区别除外)是,默认情况下,方法将上下文( this )设置为引用它们所属的对象。 In this case inside of toString function this equals to str . 在这种情况下,在toString函数内部, this等于str

Note : Accessing a property (as in str.length ) could in effect call a getter function but it depends on how the object is defined, and is in fact transparent for the user. 注意 :访问属性(如str.length )实际上可以调用getter函数,但这取决于对象的定义方式,并且实际上对用户是透明的。

JavaScript is based around objects. JavaScript基于对象。 Objects have properties (eg a User object may have name and age properties). 对象具有属性(例如,用户对象可能具有nameage属性)。 These are what define the user and are related to the user. 这些是定义用户并与用户相关的东西。 Properties are accessed via dot-notation or brackets notation (to access Eliott's age, we'll use either eliott.age or eliott['age'] — these are equivalent). 通过点符号或方括号符号来访问属性(要访问Eliott的年龄,我们将使用eliott.ageeliott['age'] -它们是等效的)。

These properties can be of any type — String, Number, Object, you name it — even functions. 这些属性可以是任何类型-字符串,数字,对象,您可以将其命名-甚至是函数。 Now the proper syntax to call a function in JS is to put round brackets: eliott.sayHello() . 现在,在JS中调用函数的正确语法是放在方括号中: eliott.sayHello() This snippet actually fetches Eliott's sayHello property, and calls it right away. 该代码段实际上获取了Eliott的sayHello属性,并立即对其进行了调用。

You can see Eliott as a box of properties, some of which can be functions. 您可以将Eliott视为一个属性框,其中一些可以是函数。 They only exist within the box and have no meaning out of the box: what would age be? 它们仅存在于框内,没有框外的意义: age将是多少? Whose age? 谁的年龄? Who's saying hello? 谁在打招呼?

Now some functions are defined at the global level: parseInt or isNaN for instance. 现在,在全局级别上定义了一些函数:例如parseIntisNaN These functions actually belong to the global box, named window (because legacy). 这些功能实际上属于全球票房,取名window (因为传统)。 You can also call them like that: window.parseInt(a, 10) or window.isNaN(a) . 您也可以这样称呼它们: window.parseInt(a, 10)window.isNaN(a) Omitting window is allowed for brevity. 为了简洁起见,省略了window

var eliott = {
  name: 'Eliott',
  age: 32,
  sayHello: function () { console.log('Hello, I’m Eliott'); }
};

eliott.name;       // access the `name` property
eliott.age;        // access the `age` property
eliott.sayHello;   // access the `sayHello` property

eliott.sayHello(); // access the `sayHello` property and calls the function

sayHello(eliott);  // Reference error: `window.sayHello` is undefined!

Note: Some types ( String , Number , Boolean , etc.) are not real objects but do have properties. 注意:某些类型( StringNumberBoolean等)不是真实对象,但具有属性。 That's how you can fetch the length of a string ( "hello".length ) and reword stuff ( "hello, Eliott".replace("Eliott", "Henry") ). 这样便可以获取字符串的长度( "hello".length )和重写单词( "hello, Eliott".replace("Eliott", "Henry") )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM