From 218934fa2ed1c702a6d3923d2aa2cc6b43c48684 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:43:23 -0500 Subject: initial commit --- .../guide/details_of_the_object_model/index.html | 758 +++++++++++++++++++++ .../web/javascript/guide/fonksiyonlar/index.html | 662 ++++++++++++++++++ .../javascript/guide/grammar_and_types/index.html | 640 +++++++++++++++++ files/tr/web/javascript/guide/ifadeler/index.html | 419 ++++++++++++ files/tr/web/javascript/guide/index.html | 122 ++++ .../web/javascript/guide/introduction/index.html | 134 ++++ .../guide/loops_and_iteration/index.html | 331 +++++++++ .../index.html" | 504 ++++++++++++++ 8 files changed, 3570 insertions(+) create mode 100644 files/tr/web/javascript/guide/details_of_the_object_model/index.html create mode 100644 files/tr/web/javascript/guide/fonksiyonlar/index.html create mode 100644 files/tr/web/javascript/guide/grammar_and_types/index.html create mode 100644 files/tr/web/javascript/guide/ifadeler/index.html create mode 100644 files/tr/web/javascript/guide/index.html create mode 100644 files/tr/web/javascript/guide/introduction/index.html create mode 100644 files/tr/web/javascript/guide/loops_and_iteration/index.html create mode 100644 "files/tr/web/javascript/guide/nesneler_ile_\303\247al\304\261\305\237mak/index.html" (limited to 'files/tr/web/javascript/guide') diff --git a/files/tr/web/javascript/guide/details_of_the_object_model/index.html b/files/tr/web/javascript/guide/details_of_the_object_model/index.html new file mode 100644 index 0000000000..160959eda2 --- /dev/null +++ b/files/tr/web/javascript/guide/details_of_the_object_model/index.html @@ -0,0 +1,758 @@ +--- +title: Details of the object model +slug: Web/JavaScript/Guide/Details_of_the_Object_Model +translation_of: Web/JavaScript/Guide/Details_of_the_Object_Model +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Working_with_Objects", "Web/JavaScript/Guide/Using_promises")}}
+ +

JavaScript is an object-based language based on prototypes, rather than being class-based. Because of this different basis, it can be less apparent how JavaScript allows you to create hierarchies of objects and to have inheritance of properties and their values. This chapter attempts to clarify the situation.

+ +

This chapter assumes that you are already somewhat familiar with JavaScript and that you have used JavaScript functions to create simple objects.

+ +

Class-based vs. prototype-based languages

+ +

Class-based object-oriented languages, such as Java and C++, are founded on the concept of two distinct entities: classes and instances.

+ + + +

A prototype-based language, such as JavaScript, does not make this distinction: it simply has objects. A prototype-based language has the notion of a prototypical object, an object used as a template from which to get the initial properties for a new object. Any object can specify its own properties, either when you create it or at run time. In addition, any object can be associated as the prototype for another object, allowing the second object to share the first object's properties.

+ +

Defining a class

+ +

In class-based languages, you define a class in a separate class definition. In that definition you can specify special methods, called constructors, to create instances of the class. A constructor method can specify initial values for the instance's properties and perform other processing appropriate at creation time. You use the new operator in association with the constructor method to create class instances.

+ +

JavaScript follows a similar model, but does not have a class definition separate from the constructor. Instead, you define a constructor function to create objects with a particular initial set of properties and values. Any JavaScript function can be used as a constructor. You use the new operator with a constructor function to create a new object.

+ +
+

Note that ECMAScript 2015 introduces a class declaration:

+ +
+

JavaScript classes, introduced in ECMAScript 2015, are primarily syntactical sugar over JavaScript's existing prototype-based inheritance. The class syntax does not introduce a new object-oriented inheritance model to JavaScript.

+
+
+ +

Subclasses and inheritance

+ +

In a class-based language, you create a hierarchy of classes through the class definitions. In a class definition, you can specify that the new class is a subclass of an already existing class. The subclass inherits all the properties of the superclass and additionally can add new properties or modify the inherited ones. For example, assume the Employee class includes only the name and dept properties, and Manager is a subclass of Employee that adds the reports property. In this case, an instance of the Manager class would have all three properties: name, dept, and reports.

+ +

JavaScript implements inheritance by allowing you to associate a prototypical object with any constructor function. So, you can create exactly the EmployeeManager example, but you use slightly different terminology. First you define the Employee constructor function, specifying the name and dept properties. Next, you define the Manager constructor function, calling the Employee constructor and specifying the reports property. Finally, you assign a new object derived from Employee.prototype as the prototype for the Manager constructor function. Then, when you create a new Manager, it inherits the name and dept properties from the Employee object.

+ +

Adding and removing properties

+ +

In class-based languages, you typically create a class at compile time and then you instantiate instances of the class either at compile time or at run time. You cannot change the number or the type of properties of a class after you define the class. In JavaScript, however, at run time you can add or remove properties of any object. If you add a property to an object that is used as the prototype for a set of objects, the objects for which it is the prototype also get the new property.

+ +

Summary of differences

+ +

The following table gives a short summary of some of these differences. The rest of this chapter describes the details of using JavaScript constructors and prototypes to create an object hierarchy and compares this to how you would do it in Java.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Comparison of class-based (Java) and prototype-based (JavaScript) object systems
CategoryClass-based (Java)Prototype-based (JavaScript)
Class vs. InstanceClass and instance are distinct entities.Tüm nesneler başka bir nesneden miras alabilir.
DefinitionDefine a class with a class definition; instantiate a class with constructor methods.Define and create a set of objects with constructor functions.
Creation of new objectnew operatörü ile tek bir nesne oluşturulur.Aynı.
Construction of object hierarchyConstruct an object hierarchy by using class definitions to define subclasses of existing classes. +

Construct an object hierarchy by assigning an object as the prototype associated with a constructor function.

+
Inheritance modelInherit properties by following the class chain.Inherit properties by following the prototype chain.
Extension of propertiesClass definition specifies all properties of all instances of a class. Cannot add properties dynamically at run time.Constructor function or prototype specifies an initial set of properties. Can add or remove properties dynamically to individual objects or to the entire set of objects.
+ +

The employee example

+ +

The remainder of this chapter uses the employee hierarchy shown in the following figure.

+ +
+
+

A simple object hierarchy with the following objects:

+ +

+
+ +
+
    +
  • Employee has the properties name (whose value defaults to the empty string) and dept (whose value defaults to "general").
  • +
  • Manager is based on Employee. It adds the reports property (whose value defaults to an empty array, intended to have an array of Employee objects as its value).
  • +
  • WorkerBee is also based on Employee. It adds the projects property (whose value defaults to an empty array, intended to have an array of strings as its value).
  • +
  • SalesPerson is based on WorkerBee. It adds the quota property (whose value defaults to 100). It also overrides the dept property with the value "sales", indicating that all salespersons are in the same department.
  • +
  • Engineer is based on WorkerBee. It adds the machine property (whose value defaults to the empty string) and also overrides the dept property with the value "engineering".
  • +
+
+
+ +

Creating the hierarchy

+ +

There are several ways to define appropriate constructor functions to implement the Employee hierarchy. How you choose to define them depends largely on what you want to be able to do in your application.

+ +

This section shows how to use very simple (and comparatively inflexible) definitions to demonstrate how to get the inheritance to work. In these definitions, you cannot specify any property values when you create an object. The newly-created object simply gets the default values, which you can change at a later time.

+ +

In a real application, you would probably define constructors that allow you to provide property values at object creation time (see More flexible constructors for information). For now, these simple definitions demonstrate how the inheritance occurs.

+ +

The following Java and JavaScript Employee definitions are similar. The only difference is that you need to specify the type for each property in Java but not in JavaScript (this is due to Java being a strongly typed language while JavaScript is a weakly typed language).

+ +
+

JavaScript

+ +
function Employee() {
+  this.name = '';
+  this.dept = 'general';
+}
+
+ +


+ Java

+ +
public class Employee {
+   public String name = "";
+   public String dept = "general";
+}
+
+
+ +

The Manager and WorkerBee definitions show the difference in how to specify the next object higher in the inheritance chain. In JavaScript, you add a prototypical instance as the value of the prototype property of the constructor function, then override the prototype.constructor to the constructor function. You can do so at any time after you define the constructor. In Java, you specify the superclass within the class definition. You cannot change the superclass outside the class definition.

+ +
+

JavaScript

+ +
function Manager() {
+  Employee.call(this);
+  this.reports = [];
+}
+Manager.prototype = Object.create(Employee.prototype);
+Manager.prototype.constructor = Manager;
+
+function WorkerBee() {
+  Employee.call(this);
+  this.projects = [];
+}
+WorkerBee.prototype = Object.create(Employee.prototype);
+WorkerBee.prototype.constructor = WorkerBee;
+
+ +


+ Java

+ +
public class Manager extends Employee {
+   public Employee[] reports =
+       new Employee[0];
+}
+
+
+
+public class WorkerBee extends Employee {
+   public String[] projects = new String[0];
+}
+
+
+
+
+ +

 

+ +

The Engineer and SalesPerson definitions create objects that descend from WorkerBee and hence from Employee. An object of these types has properties of all the objects above it in the chain. In addition, these definitions override the inherited value of the dept property with new values specific to these objects.

+ +
+

JavaScript

+ +
function SalesPerson() {
+   WorkerBee.call(this);
+   this.dept = 'sales';
+   this.quota = 100;
+}
+SalesPerson.prototype = Object.create(WorkerBee.prototype);
+SalesPerson.prototype.constructor = SalesPerson;
+
+function Engineer() {
+   WorkerBee.call(this);
+   this.dept = 'engineering';
+   this.machine = '';
+}
+Engineer.prototype = Object.create(WorkerBee.prototype)
+Engineer.prototype.constructor = Engineer;
+
+ +


+ Java

+ +
public class SalesPerson extends WorkerBee {
+   public String dept = "sales";
+   public double quota = 100.0;
+}
+
+
+public class Engineer extends WorkerBee {
+   public String dept = "engineering";
+   public String machine = "";
+}
+
+
+
+ +

Using these definitions, you can create instances of these objects that get the default values for their properties. The next figure illustrates using these JavaScript definitions to create new objects and shows the property values for the new objects.

+ +
+

Note: The term instance has a specific technical meaning in class-based languages. In these languages, an instance is an individual instantiation of a class and is fundamentally different from a class. In JavaScript, "instance" does not have this technical meaning because JavaScript does not have this difference between classes and instances. However, in talking about JavaScript, "instance" can be used informally to mean an object created using a particular constructor function. So, in this example, you could informally say that jane is an instance of Engineer. Similarly, although the terms parent, child, ancestor, and descendant do not have formal meanings in JavaScript; you can use them informally to refer to objects higher or lower in the prototype chain.

+
+ +

Creating objects with simple definitions

+ +
+

Object hierarchy

+ +

The following hierarchy is created using the code on the right side.

+ +

+ +

 

+ +

Individual objects = Jim, Sally, Mark, Fred, Jane, etc.
+ "Instances" created from constructor

+ +
var jim = new Employee;
+// Parentheses can be omitted if the
+// constructor takes no arguments.
+// jim.name is ''
+// jim.dept is 'general'
+
+var sally = new Manager;
+// sally.name is ''
+// sally.dept is 'general'
+// sally.reports is []
+
+var mark = new WorkerBee;
+// mark.name is ''
+// mark.dept is 'general'
+// mark.projects is []
+
+var fred = new SalesPerson;
+// fred.name is ''
+// fred.dept is 'sales'
+// fred.projects is []
+// fred.quota is 100
+
+var jane = new Engineer;
+// jane.name is ''
+// jane.dept is 'engineering'
+// jane.projects is []
+// jane.machine is ''
+
+
+ +

Object properties

+ +

This section discusses how objects inherit properties from other objects in the prototype chain and what happens when you add a property at run time.

+ +

Inheriting properties

+ +

Suppose you create the mark object as a WorkerBee with the following statement:

+ +
var mark = new WorkerBee;
+
+ +

When JavaScript sees the new operator, it creates a new generic object and implicitly sets the value of the internal property [[Prototype]] to the value of WorkerBee.prototype and passes this new object as the value of the this keyword to the WorkerBee constructor function. The internal [[Prototype]] property determines the prototype chain used to return property values. Once these properties are set, JavaScript returns the new object and the assignment statement sets the variable mark to that object.

+ +

This process does not explicitly put values in the mark object (local values) for the properties that mark inherits from the prototype chain. When you ask for the value of a property, JavaScript first checks to see if the value exists in that object. If it does, that value is returned. If the value is not there locally, JavaScript checks the prototype chain (using the internal [[Prototype]] property). If an object in the prototype chain has a value for the property, that value is returned. If no such property is found, JavaScript says the object does not have the property. In this way, the mark object has the following properties and values:

+ +
mark.name = '';
+mark.dept = 'general';
+mark.projects = [];
+
+ +

The mark object is assigned local values for the name and dept properties by the Employee constructor. It is assigned a local value for the projects property by the WorkerBee constructor. This gives you inheritance of properties and their values in JavaScript. Some subtleties of this process are discussed in Property inheritance revisited.

+ +

Because these constructors do not let you supply instance-specific values, this information is generic. The property values are the default ones shared by all new objects created from WorkerBee. You can, of course, change the values of any of these properties. So, you could give specific information for mark as follows:

+ +
mark.name = 'Doe, Mark';
+mark.dept = 'admin';
+mark.projects = ['navigator'];
+ +

Adding properties

+ +

In JavaScript, you can add properties to any object at run time. You are not constrained to use only the properties provided by the constructor function. To add a property that is specific to a single object, you assign a value to the object, as follows:

+ +
mark.bonus = 3000;
+
+ +

Now, the mark object has a bonus property, but no other WorkerBee has this property.

+ +

If you add a new property to an object that is being used as the prototype for a constructor function, you add that property to all objects that inherit properties from the prototype. For example, you can add a specialty property to all employees with the following statement:

+ +
Employee.prototype.specialty = 'none';
+
+ +

As soon as JavaScript executes this statement, the mark object also has the specialty property with the value of "none". The following figure shows the effect of adding this property to the Employee prototype and then overriding it for the Engineer prototype.

+ +


+ Adding properties

+ +

More flexible constructors

+ +

The constructor functions shown so far do not let you specify property values when you create an instance. As with Java, you can provide arguments to constructors to initialize property values for instances. The following figure shows one way to do this.

+ +


+ Specifying properties in a constructor, take 1

+ +

The following table shows the Java and JavaScript definitions for these objects.

+ +
+

JavaScript

+ +

Java

+
+ +
+
function Employee(name, dept) {
+  this.name = name || '';
+  this.dept = dept || 'general';
+}
+
+ +

 

+ +

 

+ +

 

+ +

 

+ +

 

+ +
public class Employee {
+   public String name;
+   public String dept;
+   public Employee () {
+      this("", "general");
+   }
+   public Employee (String name) {
+      this(name, "general");
+   }
+   public Employee (String name, String dept) {
+      this.name = name;
+      this.dept = dept;
+   }
+}
+
+
+ +
+
function WorkerBee(projs) {
+
+ this.projects = projs || [];
+}
+WorkerBee.prototype = new Employee;
+
+ +

 

+ +

 

+ +

 

+ +
public class WorkerBee extends Employee {
+   public String[] projects;
+   public WorkerBee () {
+      this(new String[0]);
+   }
+   public WorkerBee (String[] projs) {
+      projects = projs;
+   }
+}
+
+
+ +
+
+function Engineer(mach) {
+   this.dept = 'engineering';
+   this.machine = mach || '';
+}
+Engineer.prototype = new WorkerBee;
+
+ +

 

+ +

 

+ +

 

+ +
public class Engineer extends WorkerBee {
+   public String machine;
+   public Engineer () {
+      dept = "engineering";
+      machine = "";
+   }
+   public Engineer (String mach) {
+      dept = "engineering";
+      machine = mach;
+   }
+}
+
+
+ +

These JavaScript definitions use a special idiom for setting default values:

+ +
this.name = name || '';
+
+ +

The JavaScript logical OR operator (||) evaluates its first argument. If that argument converts to true, the operator returns it. Otherwise, the operator returns the value of the second argument. Therefore, this line of code tests to see if name has a useful value for the name property. If it does, it sets this.name to that value. Otherwise, it sets this.name to the empty string. This chapter uses this idiom for brevity; however, it can be puzzling at first glance.

+ +
+

Note: This may not work as expected if the constructor function is called with arguments which convert to false (like 0 (zero) and empty string (""). In this case the default value will be chosen.

+
+ +

With these definitions, when you create an instance of an object, you can specify values for the locally defined properties. You can use the following statement to create a new Engineer:

+ +
var jane = new Engineer('belau');
+
+ +

Jane's properties are now:

+ +
jane.name == '';
+jane.dept == 'engineering';
+jane.projects == [];
+jane.machine == 'belau';
+
+ +

Notice that with these definitions, you cannot specify an initial value for an inherited property such as name. If you want to specify an initial value for inherited properties in JavaScript, you need to add more code to the constructor function.

+ +

So far, the constructor function has created a generic object and then specified local properties and values for the new object. You can have the constructor add more properties by directly calling the constructor function for an object higher in the prototype chain. The following figure shows these new definitions.

+ +


+ Specifying properties in a constructor, take 2

+ +

Let's look at one of these definitions in detail. Here's the new definition for the Engineer constructor:

+ +
function Engineer(name, projs, mach) {
+  this.base = WorkerBee;
+  this.base(name, 'engineering', projs);
+  this.machine = mach || '';
+}
+
+ +

Suppose you create a new Engineer object as follows:

+ +
var jane = new Engineer('Doe, Jane', ['navigator', 'javascript'], 'belau');
+
+ +

JavaScript follows these steps:

+ +
    +
  1. The new operator creates a generic object and sets its __proto__ property to Engineer.prototype.
  2. +
  3. The new operator passes the new object to the Engineer constructor as the value of the this keyword.
  4. +
  5. The constructor creates a new property called base for that object and assigns the value of the WorkerBee constructor to the base property. This makes the WorkerBee constructor a method of the Engineer object. The name of the base property is not special. You can use any legal property name; base is simply evocative of its purpose.
  6. +
  7. The constructor calls the base method, passing as its arguments two of the arguments passed to the constructor ("Doe, Jane" and ["navigator", "javascript"]) and also the string "engineering". Explicitly using "engineering" in the constructor indicates that all Engineer objects have the same value for the inherited dept property, and this value overrides the value inherited from Employee.
  8. +
  9. Because base is a method of Engineer, within the call to base, JavaScript binds the this keyword to the object created in Step 1. Thus, the WorkerBee function in turn passes the "Doe, Jane" and "engineering" arguments to the Employee constructor function. Upon return from the Employee constructor function, the WorkerBee function uses the remaining argument to set the projects property.
  10. +
  11. Upon return from the base method, the Engineer constructor initializes the object's machine property to "belau".
  12. +
  13. Upon return from the constructor, JavaScript assigns the new object to the jane variable.
  14. +
+ +

You might think that, having called the WorkerBee constructor from inside the Engineer constructor, you have set up inheritance appropriately for Engineer objects. This is not the case. Calling the WorkerBee constructor ensures that an Engineer object starts out with the properties specified in all constructor functions that are called. However, if you later add properties to the Employee or WorkerBee prototypes, those properties are not inherited by the Engineer object. For example, assume you have the following statements:

+ +
function Engineer(name, projs, mach) {
+  this.base = WorkerBee;
+  this.base(name, 'engineering', projs);
+  this.machine = mach || '';
+}
+var jane = new Engineer('Doe, Jane', ['navigator', 'javascript'], 'belau');
+Employee.prototype.specialty = 'none';
+
+ +

The jane object does not inherit the specialty property. You still need to explicitly set up the prototype to ensure dynamic inheritance. Assume instead you have these statements:

+ +
function Engineer(name, projs, mach) {
+  this.base = WorkerBee;
+  this.base(name, 'engineering', projs);
+  this.machine = mach || '';
+}
+Engineer.prototype = new WorkerBee;
+var jane = new Engineer('Doe, Jane', ['navigator', 'javascript'], 'belau');
+Employee.prototype.specialty = 'none';
+
+ +

Now the value of the jane object's specialty property is "none".

+ +

Another way of inheriting is by using the call() / apply() methods. Below are equivalent:

+ +
+
function Engineer(name, projs, mach) {
+  this.base = WorkerBee;
+  this.base(name, 'engineering', projs);
+  this.machine = mach || '';
+}
+
+ +
function Engineer(name, projs, mach) {
+  WorkerBee.call(this, name, 'engineering', projs);
+  this.machine = mach || '';
+}
+
+
+ +

Using the javascript call() method makes a cleaner implementation because the base is not needed anymore.

+ +

Property inheritance revisited

+ +

The preceding sections described how JavaScript constructors and prototypes provide hierarchies and inheritance. This section discusses some subtleties that were not necessarily apparent in the earlier discussions.

+ +

Local versus inherited values

+ +

When you access an object property, JavaScript performs these steps, as described earlier in this chapter:

+ +
    +
  1. Check to see if the value exists locally. If it does, return that value.
  2. +
  3. If there is not a local value, check the prototype chain (using the __proto__ property).
  4. +
  5. If an object in the prototype chain has a value for the specified property, return that value.
  6. +
  7. If no such property is found, the object does not have the property.
  8. +
+ +

The outcome of these steps depends on how you define things along the way. The original example had these definitions:

+ +
function Employee() {
+  this.name = '';
+  this.dept = 'general';
+}
+
+function WorkerBee() {
+  this.projects = [];
+}
+WorkerBee.prototype = new Employee;
+
+ +

With these definitions, suppose you create amy as an instance of WorkerBee with the following statement:

+ +
var amy = new WorkerBee;
+
+ +

The amy object has one local property, projects. The values for the name and dept properties are not local to amy and so derive from the amy object's __proto__ property. Thus, amy has these property values:

+ +
amy.name == '';
+amy.dept == 'general';
+amy.projects == [];
+
+ +

Now suppose you change the value of the name property in the prototype associated with Employee:

+ +
Employee.prototype.name = 'Unknown';
+
+ +

At first glance, you might expect that new value to propagate down to all the instances of Employee. However, it does not.

+ +

When you create any instance of the Employee object, that instance gets a local value for the name property (the empty string). This means that when you set the WorkerBee prototype by creating a new Employee object, WorkerBee.prototype has a local value for the name property. Therefore, when JavaScript looks up the name property of the amy object (an instance of WorkerBee), JavaScript finds the local value for that property in WorkerBee.prototype. It therefore does not look further up the chain to Employee.prototype.

+ +

If you want to change the value of an object property at run time and have the new value be inherited by all descendants of the object, you cannot define the property in the object's constructor function. Instead, you add it to the constructor's associated prototype. For example, assume you change the preceding code to the following:

+ +
function Employee() {
+  this.dept = 'general';    // Note that this.name (a local variable) does not appear here
+}
+Employee.prototype.name = '';    // A single copy
+
+function WorkerBee() {
+  this.projects = [];
+}
+WorkerBee.prototype = new Employee;
+
+var amy = new WorkerBee;
+
+Employee.prototype.name = 'Unknown';
+
+ +

In this case, the name property of amy becomes "Unknown".

+ +

As these examples show, if you want to have default values for object properties and you want to be able to change the default values at run time, you should set the properties in the constructor's prototype, not in the constructor function itself.

+ +

Determining instance relationships

+ +

Property lookup in JavaScript looks within an object's own properties and, if the property name is not found, it looks within the special object property __proto__. This continues recursively; the process is called "lookup in the prototype chain".

+ +

The special property __proto__ is set when an object is constructed; it is set to the value of the constructor's prototype property. So the expression new Foo() creates an object with __proto__ == Foo.prototype. Consequently, changes to the properties of Foo.prototype alters the property lookup for all objects that were created by new Foo().

+ +

Every object has a __proto__ object property (except Object); every function has a prototype object property. So objects can be related by 'prototype inheritance' to other objects. You can test for inheritance by comparing an object's __proto__ to a function's prototype object. JavaScript provides a shortcut: the instanceof operator tests an object against a function and returns true if the object inherits from the function prototype. For example,

+ +
var f = new Foo();
+var isTrue = (f instanceof Foo);
+ +

For a more detailed example, suppose you have the same set of definitions shown in Inheriting properties. Create an Engineer object as follows:

+ +
var chris = new Engineer('Pigman, Chris', ['jsd'], 'fiji');
+
+ +

With this object, the following statements are all true:

+ +
chris.__proto__ == Engineer.prototype;
+chris.__proto__.__proto__ == WorkerBee.prototype;
+chris.__proto__.__proto__.__proto__ == Employee.prototype;
+chris.__proto__.__proto__.__proto__.__proto__ == Object.prototype;
+chris.__proto__.__proto__.__proto__.__proto__.__proto__ == null;
+
+ +

Given this, you could write an instanceOf function as follows:

+ +
function instanceOf(object, constructor) {
+   object = object.__proto__;
+   while (object != null) {
+      if (object == constructor.prototype)
+         return true;
+      if (typeof object == 'xml') {
+        return constructor.prototype == XML.prototype;
+      }
+      object = object.__proto__;
+   }
+   return false;
+}
+
+ +
Note: The implementation above checks the type of the object against "xml" in order to work around a quirk of how XML objects are represented in recent versions of JavaScript. See {{ bug(634150) }} if you want the nitty-gritty details.
+ +

Using the instanceOf function defined above, these expressions are true:

+ +
instanceOf(chris, Engineer)
+instanceOf(chris, WorkerBee)
+instanceOf(chris, Employee)
+instanceOf(chris, Object)
+
+ +

But the following expression is false:

+ +
instanceOf(chris, SalesPerson)
+
+ +

Global information in constructors

+ +

When you create constructors, you need to be careful if you set global information in the constructor. For example, assume that you want a unique ID to be automatically assigned to each new employee. You could use the following definition for Employee:

+ +
var idCounter = 1;
+
+function Employee(name, dept) {
+   this.name = name || '';
+   this.dept = dept || 'general';
+   this.id = idCounter++;
+}
+
+ +

With this definition, when you create a new Employee, the constructor assigns it the next ID in sequence and then increments the global ID counter. So, if your next statement is the following, victoria.id is 1 and harry.id is 2:

+ +
var victoria = new Employee('Pigbert, Victoria', 'pubs');
+var harry = new Employee('Tschopik, Harry', 'sales');
+
+ +

At first glance that seems fine. However, idCounter gets incremented every time an Employee object is created, for whatever purpose. If you create the entire Employee hierarchy shown in this chapter, the Employee constructor is called every time you set up a prototype. Suppose you have the following code:

+ +
var idCounter = 1;
+
+function Employee(name, dept) {
+   this.name = name || '';
+   this.dept = dept || 'general';
+   this.id = idCounter++;
+}
+
+function Manager(name, dept, reports) {...}
+Manager.prototype = new Employee;
+
+function WorkerBee(name, dept, projs) {...}
+WorkerBee.prototype = new Employee;
+
+function Engineer(name, projs, mach) {...}
+Engineer.prototype = new WorkerBee;
+
+function SalesPerson(name, projs, quota) {...}
+SalesPerson.prototype = new WorkerBee;
+
+var mac = new Engineer('Wood, Mac');
+
+ +

Further assume that the definitions omitted here have the base property and call the constructor above them in the prototype chain. In this case, by the time the mac object is created, mac.id is 5.

+ +

Depending on the application, it may or may not matter that the counter has been incremented these extra times. If you care about the exact value of this counter, one possible solution involves instead using the following constructor:

+ +
function Employee(name, dept) {
+   this.name = name || '';
+   this.dept = dept || 'general';
+   if (name)
+      this.id = idCounter++;
+}
+
+ +

When you create an instance of Employee to use as a prototype, you do not supply arguments to the constructor. Using this definition of the constructor, when you do not supply arguments, the constructor does not assign a value to the id and does not update the counter. Therefore, for an Employee to get an assigned id, you must specify a name for the employee. In this example, mac.id would be 1.

+ +

Alternatively, you can create a copy of Employee's prototype object to assign to WorkerBee:

+ +
WorkerBee.prototype = Object.create(Employee.prototype);
+// instead of WorkerBee.prototype = new Employee
+
+ +

No multiple inheritance

+ +

Some object-oriented languages allow multiple inheritance. That is, an object can inherit the properties and values from unrelated parent objects. JavaScript does not support multiple inheritance.

+ +

Inheritance of property values occurs at run time by JavaScript searching the prototype chain of an object to find a value. Because an object has a single associated prototype, JavaScript cannot dynamically inherit from more than one prototype chain.

+ +

In JavaScript, you can have a constructor function call more than one other constructor function within it. This gives the illusion of multiple inheritance. For example, consider the following statements:

+ +
function Hobbyist(hobby) {
+   this.hobby = hobby || 'scuba';
+}
+
+function Engineer(name, projs, mach, hobby) {
+   this.base1 = WorkerBee;
+   this.base1(name, 'engineering', projs);
+   this.base2 = Hobbyist;
+   this.base2(hobby);
+   this.machine = mach || '';
+}
+Engineer.prototype = new WorkerBee;
+
+var dennis = new Engineer('Doe, Dennis', ['collabra'], 'hugo');
+
+ +

Further assume that the definition of WorkerBee is as used earlier in this chapter. In this case, the dennis object has these properties:

+ +
dennis.name == 'Doe, Dennis';
+dennis.dept == 'engineering';
+dennis.projects == ['collabra'];
+dennis.machine == 'hugo';
+dennis.hobby == 'scuba';
+
+ +

So dennis does get the hobby property from the Hobbyist constructor. However, assume you then add a property to the Hobbyist constructor's prototype:

+ +
Hobbyist.prototype.equipment = ['mask', 'fins', 'regulator', 'bcd'];
+
+ +

The dennis object does not inherit this new property.

+ +
{{PreviousNext("Web/JavaScript/Guide/Working_with_Objects", "Web/JavaScript/Guide/Using_promises")}}
diff --git a/files/tr/web/javascript/guide/fonksiyonlar/index.html b/files/tr/web/javascript/guide/fonksiyonlar/index.html new file mode 100644 index 0000000000..e688bd5dcb --- /dev/null +++ b/files/tr/web/javascript/guide/fonksiyonlar/index.html @@ -0,0 +1,662 @@ +--- +title: Fonksiyonlar +slug: Web/JavaScript/Guide/Fonksiyonlar +tags: + - Başlangıç seviyesi + - Fonksiyonlar + - Rehber +translation_of: Web/JavaScript/Guide/Functions +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Loops_and_iteration", "Web/JavaScript/Guide/Expressions_and_Operators")}}
+ +

Foksiyonlar, JavaScript'in en temel yapıtaşlarından biridir. Her bir fonksiyon, bir JavaScript işlemidir—herhangi bir görevi yerine getiren  veya değer hesaplayan bir ifade kümesini içerirler. Bir fonksiyonu kullanmak için, fonksiyonu çağıracağınız kısmın faaliyet gösterdiği alanda fonksiyonu tanımlıyor olmanız gerekmektedir.

+ +

Daha fazla bilgi için JavaScript fonksiyonları ile ilgili buradaki detaylı kaynağı inceleyebilirsiniz.

+ +

Fonksiyonların tanımlanması

+ +

Fonksiyon tanımlamaları

+ +

Bir fonksiyon tanımı (fonksiyon betimlemesi, veya fonksiyon ifadesi de denir)  function anahtar kelimesinden sonra aşağıdaki kısımları içerir:

+ + + +

Örneğin aşağıdaki kodda karesiniAl isimli basit bir fonksiyon tanımlanmıştır:

+ +
function karesiniAl(sayı) {
+  return sayı * sayı;
+}
+
+ +

karesiniAl fonksiyonu, sayı isminde tek bir parametre içerir. Tek bir ifade içeren fonksiyonda, sayı parametresinin kendisi ile çarpılıp geri döndürülmesi işlemi yapılmıştır. return ifadesi, fonksiyon tarafından döndürülen değeri belirler.

+ +
return sayı * sayı;
+
+ +

Sayı türünde olduğu gibi ilkel parametreler fonksiyonlara değer ile geçilirler; ilgili değer, fonksiyona parametre olarak geçildiğinde parametre değerinin fonksiyonda ayrı bir kopyası alınır, eğer fonksiyon içerisinde parametre değerinde değişik yapılırsa, bu değişiklik sadece kopyalanan değer üzerinde gerçekleşmiştir, fonksiyona geçilen asıl değer değişmez.

+ +

Eğer bir nesneyi ({{jsxref("Array")}} veya bir kullanıcı tanımlı nesne gibi ilkel olmayan değer) fonksiyona parametre olarak geçerseniz, nesne fonksiyon içerisinde kopyalanmadığı için nesne üzerinde yapılan değişiklikler fonksiyon dışında da korunur. Aşağıdaki örneği inceleyelim:

+ +
function arabamıDeğiştir(araba) {
+  araba.markası = "Toyota";
+}
+
+var arabam = {markası: "Honda", modeli: "Accord", yılı: 1998};
+var x, y;
+
+x = arabam.markası ; // "Honda" değerini getirir
+
+arabamıDeğiştir(arabam);
+y = arabam.markası; // "Toyota" değeri döndürülür
+                    // (markası özelliği fonksiyon tarafından değiştirilmiştir)
+
+ +

Fonksiyon ifadeleri

+ +

Yukarıdaki fonksiyon tanımlaması sözdizimsel olarak bir ifade olmasına rağmen, fonksiyonlar ayrıca bir fonksiyon ifadesi ile de oluşturulabilirler. Böyle bir fonksiyon anonim olabilir; bir isme sahip olmak zorunda değildir. Örnek olarak, matematikteki kare alma fonksiyonu aşağıdaki şekilde tanımlanabilir:

+ +
var karesiniAl = function(sayı) { return sayı * sayı };
+var x = karesiniAl(4) // x'in değeri 16 olur.
+ +

Fonksiyon ifadesi ile belirtilen fonksiyon adı, fonksiyonun içerisinde kendisini çağıracak şekilde kullanılabilir:

+ +
var faktoriyel = function fa(n) { return n < 2 ? 1 : n * fa(n-1) };
+
+console.log(faktoriyel(3));
+
+ +

Fonksiyon ifadeleri, bir fonksiyon diğer fonksiyona parametre olarak geçilirken oldukça elverişlidir. Aşağıdaki örnekte map fonksiyonu tanımlanmış ve ilk parametresinde başka bir fonksiyonu parametre olarak almıştır:

+ +
function map(f,d) {
+  var sonuç = [], // Yeni bir dizi
+      i;
+  for (i = 0; i != d.length; i++)
+    sonuç[i] = f(d[i]);
+  return sonuç;
+}
+
+ +

Aşağıdaki kodda kullanımı mevcuttur:

+ +
var çarpım = function(x) {return x * x * x}; // Fonksiyon ifadesi.
+map(çarpım, [0, 1, 2, 5, 10]);
+
+ +

[0, 1, 8, 125, 1000] dizisini döndürür.

+ +

JavaScript'te bir fonksiyon, herhangi bir duruma bağlı olarak oluşturulabilir.Örneğin aşağıdaki fonksiyonda benimFonk fonksiyonu, sayı değeri sadece 0'a eşit olursa tanımlanır:

+ +
var benimFonk;
+if (sayı === 0){
+  benimFonk = function(araba) {
+    araba.marka = "Toyota"
+  }
+}
+ +

Burada tanımlanan fonksiyonlara ek olarak {{jsxref("Function")}} yapıcısını kullanarak da çalışma zamanında fonksiyon oluşmasını sağlanabilir. Örneğin {{jsxref("eval", "eval()")}} ifadesi gibi.

+ +

Bir nesnenin özelliği olan fonksiyona metot adı verilir. Nesneler ve metotlar hakkında daha fazla bilgi için bkz: Nesneler ile çalışma.

+ +

Fonksiyonları çağırma

+ +

Bir fonksiyonu tanımlamakla o fonksiyon çalışmaz. Fonksiyonu tanımlamak kısaca, o fonksiyona bir isim vermek ve o fonkisyon çağırıldığında bizim için hangi eylemleri yapması gerektiğini belirtmektir. Fonksiyonu çağırmak, bu belirlenmiş eylemleri bizim o fonksiyona verdiğimiz parametrelerin de kullanılmasıyla gerçekleştirir.  Örneğin,  karesiniAl diye bir fonksiyon tanımladığınızda, o fonksiyonu aşağıdaki gibi çağırabilirsiniz:

+ +
karesiniAl(5);
+
+ +

Bu ifade, fonksiyona parametre olarak 5 sayısını yollayarak çağırır. Fonksiyon, tanımlanırken belirttiğimiz eylemleri yapar ve bize 25 değerini döndürür.

+ +

Fonksiyonlar çağrıldıklarında bir alanda olmalıdılar, fakat fonksiyon bildirimi kaldırılabilir, örnekteki gibi:

+ +
console.log(square(5));
+/* ... */
+function square(n) { return n * n }
+
+ +

Bir fonksiyonun alanı, bildirilen işlevdir, veya tüm program üst seviyede bildirilmişse.

+ +
+

Not:  Bu, yalnızca yukarıdaki sözdizimini (i.e. function benimFonk(){}) işlevini kullanarak işlevi tanımlarken çalışır. Aşağıdaki kod çalışmayacak. Yani, işlev kaldırma sadece işlev bildirimi ile çalışır ve işlev ifadesiyle çalışamaz.

+
+ +
console.log(square); // square is hoisted with an initial value undefined.
+console.log(square(5)); // TypeError: square is not a function
+var square = function (n) {
+  return n * n;
+}
+
+ +

Bir fonksiyonun argümanları karakter dizileri ve sayılarla sınırlı değildir. Tüm nesneleri bir fonksiyona aktarabilirsiniz. show_props() fonksiyonu (Working with objects bölümünde tanımlanmıştır.) nesneyi argüman olarak alan bir fonksiyon örneğidir.

+ +

Bir fonksiyon kendini çağırabilir. Örneğin, burada faktöriyelleri yinelemeli olarak hesaplayan bir fonksiyon var.

+ +
function factorial(n){
+  if ((n === 0) || (n === 1))
+    return 1;
+  else
+    return (n * factorial(n - 1));
+}
+
+ +

Daha sonra bir ile beş arasındaki faktöriyelleri şu şekilde hesaplayabilirsiniz:

+ +
var a, b, c, d, e;
+a = factorial(1); // a gets the value 1
+b = factorial(2); // b gets the value 2
+c = factorial(3); // c gets the value 6
+d = factorial(4); // d gets the value 24
+e = factorial(5); // e gets the value 120
+
+ +

Fonksiyonları  çağırmanın başka yolları da var. Bir fonksiyonun dinamik olarak çağrılması gerektiği veya bir fonksiyonun argümanlarının sayısının değişebileceği veya fonksiyon çağrısının içeriğinin çalışma zamanında belirlenen belirli bir nesneye ayarlanması gerektiği durumlar vardır. Fonksiyonların kendileri nesneler olduğu ve bu nesnelerin sırasıyla yöntemleri olduğu anlaşılıyor (bkz. {{Jsxref ("Function")}} nesnesi). Bunlardan biri, {{jsxref ("Function.apply", "application ()")}} yöntemi, bu amaca ulaşmak için kullanılabilir.

+ +

Fonksiyon Kapsamı

+ +

Bir fonksiyon içinde tanımlanmış değişkenlere, fonksiyonun dışındaki herhangi bir yerden erişilemez, çünkü değişken sadece fonksiyon kapsamında tanımlanır. Bununla birlikte, bir fonksiyon tanımlandığı kapsamda tanımlanan tüm değişkenlere ve fonksiyonlara erişebilir. Başka bir deyişle, global kapsamda tanımlanan bir fonksiyon, global kapsamda tanımlanan tüm değişkenlere erişebilir. Başka bir fonksiyonun içinde tanımlanmış bir fonksiyon, ana fonksiyonunda tanımlanan tüm değişkenlere ve ana fonksiyonun erişebildiği herhangi bir değişkene de erişebilir.

+ +
// The following variables are defined in the global scope
+var num1 = 20,
+    num2 = 3,
+    name = "Chamahk";
+
+// This function is defined in the global scope
+function multiply() {
+  return num1 * num2;
+}
+
+multiply(); // Returns 60
+
+// A nested function example
+function getScore () {
+  var num1 = 2,
+      num2 = 3;
+
+  function add() {
+    return name + " scored " + (num1 + num2);
+  }
+
+  return add();
+}
+
+getScore(); // Returns "Chamahk scored 5"
+ +

Kapsam ve fonksiyon yığını

+ +

Yineleme

+ +

Bir fonksiyon kendisine başvurabilir ve kendisini arayabilir. Bir işlevin kendisine başvurması için üç yol vardır:

+ +

 

+ +
    +
  1. fonksiyonun adı
  2. +
  3. arguments.callee
  4. +
  5. +

    fonksiyona başvuran bir kapsam içi değişken  

    +
  6. +
+ +
+
+
+

Örneğin, aşağıdaki işlev tanımını göz önünde bulundurun:

+
+
+
+ +

 

+ +
var foo = function bar() {
+   // statements go here
+};
+
+ +

Fonksiyon gövdesinde aşağıdakilerden hepsi eşdeğerdir.

+ +
    +
  1. bar()
  2. +
  3. arguments.callee()
  4. +
  5. foo()
  6. +
+ +

Kendisini çağıran fonksiyona özyinelemeli fonksiyon denir. Bazı açılardan, özyineleme bir döngüye benzer. Her ikisi de aynı kodu birkaç kez uygular ve her ikisi de bir koşul gerektirir (bu, sonsuz bir döngüden kaçınmak veya daha doğrusu bu durumda sonsuz özyinelemeden kaçınmak için). Örneğin, aşağıdaki döngü:

+ +
var x = 0;
+while (x < 10) { // "x < 10" is the loop condition
+   // do stuff
+   x++;
+}
+
+ +

özyinelemeli bir fonksiyona ve bu fonksiyonun çağrısına dönüştürülebilir:

+ +
function loop(x) {
+  if (x >= 10) // "x >= 10" is the exit condition (equivalent to "!(x < 10)")
+    return;
+  // do stuff
+  loop(x + 1); // the recursive call
+}
+loop(0);
+
+ +

Ancak, bazı algoritmalar basit yinelemeli döngüler olamaz. Örneğin, bir ağaç yapısının tüm düğümlerinin (örneğin DOM) alınması özyineleme kullanılarak daha kolay yapılır:

+ +
function walkTree(node) {
+  if (node == null) //
+    return;
+  // do something with node
+  for (var i = 0; i < node.childNodes.length; i++) {
+    walkTree(node.childNodes[i]);
+  }
+}
+
+ +

Fonksiyon döngüsü ile karşılaştırıldığında, her özyinelemeli çağrının kendisi burada birçok özyinelemeli çağrı yapar.

+ +

Herhangi bir özyinelemeli algoritmayı özyinelemeli olmayan bir algoritmaya dönüştürmek mümkündür, ancak çoğu zaman mantık çok daha karmaşıktır ve bunu yapmak bir yığının kullanılmasını gerektirir. Aslında, özyinelemenin kendisi bir yığın kullanır: Fonksiyon yığını.

+ +

Yığın benzeri davranış aşağıdaki örnekte görülebilir:

+ +
function foo(i) {
+  if (i < 0)
+    return;
+  console.log('begin:' + i);
+  foo(i - 1);
+  console.log('end:' + i);
+}
+foo(3);
+
+// Output:
+
+// begin:3
+// begin:2
+// begin:1
+// begin:0
+// end:0
+// end:1
+// end:2
+// end:3
+ +

Nested functions and closures

+ +

You can nest a function within a function. The nested (inner) function is private to its containing (outer) function. It also forms a closure. A closure is an expression (typically a function) that can have free variables together with an environment that binds those variables (that "closes" the expression).

+ +

Since a nested function is a closure, this means that a nested function can "inherit" the arguments and variables of its containing function. In other words, the inner function contains the scope of the outer function.

+ +

To summarize:

+ + + + + +

The following example shows nested functions:

+ +
function addSquares(a,b) {
+  function square(x) {
+    return x * x;
+  }
+  return square(a) + square(b);
+}
+a = addSquares(2,3); // returns 13
+b = addSquares(3,4); // returns 25
+c = addSquares(4,5); // returns 41
+
+ +

Since the inner function forms a closure, you can call the outer function and specify arguments for both the outer and inner function:

+ +
function outside(x) {
+  function inside(y) {
+    return x + y;
+  }
+  return inside;
+}
+fn_inside = outside(3); // Think of it like: give me a function that adds 3 to whatever you give it
+result = fn_inside(5); // returns 8
+
+result1 = outside(3)(5); // returns 8
+
+ +

Preservation of variables

+ +

Notice how x is preserved when inside is returned. A closure must preserve the arguments and variables in all scopes it references. Since each call provides potentially different arguments, a new closure is created for each call to outside. The memory can be freed only when the returned inside is no longer accessible.

+ +

This is not different from storing references in other objects, but is often less obvious because one does not set the references directly and cannot inspect them.

+ +

Multiply-nested functions

+ +

Functions can be multiply-nested, i.e. a function (A) containing a function (B) containing a function (C). Both functions B and C form closures here, so B can access A and C can access B. In addition, since C can access B which can access A, C can also access A. Thus, the closures can contain multiple scopes; they recursively contain the scope of the functions containing it. This is called scope chaining. (Why it is called "chaining" will be explained later.)

+ +

Consider the following example:

+ +
function A(x) {
+  function B(y) {
+    function C(z) {
+      console.log(x + y + z);
+    }
+    C(3);
+  }
+  B(2);
+}
+A(1); // logs 6 (1 + 2 + 3)
+
+ +

In this example, C accesses B's y and A's x. This can be done because:

+ +
    +
  1. B forms a closure including A, i.e. B can access A's arguments and variables.
  2. +
  3. C forms a closure including B.
  4. +
  5. Because B's closure includes A, C's closure includes A, C can access both B and A's arguments and variables. In other words, C chains the scopes of B and A in that order.
  6. +
+ +

The reverse, however, is not true. A cannot access C, because A cannot access any argument or variable of B, which C is a variable of. Thus, C remains private to only B.

+ +

Name conflicts

+ +

When two arguments or variables in the scopes of a closure have the same name, there is a name conflict. More inner scopes take precedence, so the inner-most scope takes the highest precedence, while the outer-most scope takes the lowest. This is the scope chain. The first on the chain is the inner-most scope, and the last is the outer-most scope. Consider the following:

+ +
function outside() {
+  var x = 10;
+  function inside(x) {
+    return x;
+  }
+  return inside;
+}
+result = outside()(20); // returns 20 instead of 10
+
+ +

The name conflict happens at the statement return x and is between inside's parameter x and outside's variable x. The scope chain here is {inside, outside, global object}. Therefore inside's x takes precedences over outside's x, and 20 (inside's x) is returned instead of 10 (outside's x).

+ +

Closures

+ +

Closures are one of the most powerful features of JavaScript. JavaScript allows for the nesting of functions and grants the inner function full access to all the variables and functions defined inside the outer function (and all other variables and functions that the outer function has access to). However, the outer function does not have access to the variables and functions defined inside the inner function. This provides a sort of security for the variables of the inner function. Also, since the inner function has access to the scope of the outer function, the variables and functions defined in the outer function will live longer than the outer function itself, if the inner function manages to survive beyond the life of the outer function. A closure is created when the inner function is somehow made available to any scope outside the outer function.

+ +
var pet = function(name) {   // The outer function defines a variable called "name"
+  var getName = function() {
+    return name;             // The inner function has access to the "name" variable of the outer function
+  }
+  return getName;            // Return the inner function, thereby exposing it to outer scopes
+}
+myPet = pet("Vivie");
+
+myPet();                     // Returns "Vivie"
+
+ +

It can be much more complex than the code above. An object containing methods for manipulating the inner variables of the outer function can be returned.

+ +
var createPet = function(name) {
+  var sex;
+
+  return {
+    setName: function(newName) {
+      name = newName;
+    },
+
+    getName: function() {
+      return name;
+    },
+
+    getSex: function() {
+      return sex;
+    },
+
+    setSex: function(newSex) {
+      if(typeof newSex === "string" && (newSex.toLowerCase() === "male" || newSex.toLowerCase() === "female")) {
+        sex = newSex;
+      }
+    }
+  }
+}
+
+var pet = createPet("Vivie");
+pet.getName();                  // Vivie
+
+pet.setName("Oliver");
+pet.setSex("male");
+pet.getSex();                   // male
+pet.getName();                  // Oliver
+
+ +

In the code above, the name variable of the outer function is accessible to the inner functions, and there is no other way to access the inner variables except through the inner functions. The inner variables of the inner functions act as safe stores for the outer arguments and variables. They hold "persistent", yet secure, data for the inner functions to work with. The functions do not even have to be assigned to a variable, or have a name.

+ +
var getCode = (function(){
+  var secureCode = "0]Eal(eh&2";    // A code we do not want outsiders to be able to modify...
+
+  return function () {
+    return secureCode;
+  };
+})();
+
+getCode();    // Returns the secureCode
+
+ +

There are, however, a number of pitfalls to watch out for when using closures. If an enclosed function defines a variable with the same name as the name of a variable in the outer scope, there is no way to refer to the variable in the outer scope again.

+ +
var createPet = function(name) {  // Outer function defines a variable called "name"
+  return {
+    setName: function(name) {    // Enclosed function also defines a variable called "name"
+      name = name;               // ??? How do we access the "name" defined by the outer function ???
+    }
+  }
+}
+
+ +

The magical this variable is very tricky in closures. They have to be used carefully, as what this refers to depends completely on where the function was called, rather than where it was defined.

+ +

Using the arguments object

+ +

The arguments of a function are maintained in an array-like object. Within a function, you can address the arguments passed to it as follows:

+ +
arguments[i]
+
+ +

where i is the ordinal number of the argument, starting at zero. So, the first argument passed to a function would be arguments[0]. The total number of arguments is indicated by arguments.length.

+ +

Using the arguments object, you can call a function with more arguments than it is formally declared to accept. This is often useful if you don't know in advance how many arguments will be passed to the function. You can use arguments.length to determine the number of arguments actually passed to the function, and then access each argument using the arguments object.

+ +

For example, consider a function that concatenates several strings. The only formal argument for the function is a string that specifies the characters that separate the items to concatenate. The function is defined as follows:

+ +
function myConcat(separator) {
+   var result = ""; // initialize list
+   var i;
+   // iterate through arguments
+   for (i = 1; i < arguments.length; i++) {
+      result += arguments[i] + separator;
+   }
+   return result;
+}
+
+ +

You can pass any number of arguments to this function, and it concatenates each argument into a string "list":

+ +
// returns "red, orange, blue, "
+myConcat(", ", "red", "orange", "blue");
+
+// returns "elephant; giraffe; lion; cheetah; "
+myConcat("; ", "elephant", "giraffe", "lion", "cheetah");
+
+// returns "sage. basil. oregano. pepper. parsley. "
+myConcat(". ", "sage", "basil", "oregano", "pepper", "parsley");
+
+ +
+

Note: The arguments variable is "array-like", but not an array. It is array-like in that is has a numbered index and a length property. However, it does not possess all of the array-manipulation methods.

+
+ +

See the {{jsxref("Function")}} object in the JavaScript reference for more information.

+ +

Function parameters

+ +

Starting with ECMAScript 6, there are two new kinds of parameters: default parameters and rest parameters.

+ +

Default parameters

+ +

In JavaScript, parameters of functions default to undefined. However, in some situations it might be useful to set a different default value. This is where default parameters can help.

+ +

In the past, the general strategy for setting defaults was to test parameter values in the body of the function and assign a value if they are undefined. If in the following example, no value is provided for b in the call, its value would be undefined  when evaluating a*b and the call to multiply would have returned NaN. However, this is caught with the second line in this example:

+ +
function multiply(a, b) {
+  b = typeof b !== 'undefined' ?  b : 1;
+
+  return a*b;
+}
+
+multiply(5); // 5
+
+ +

With default parameters, the check in the function body is no longer necessary. Now, you can simply put 1 as the default value for b in the function head:

+ +
function multiply(a, b = 1) {
+  return a*b;
+}
+
+multiply(5); // 5
+ +

Fore more details, see default parameters in the reference.

+ +

Rest parameters

+ +

The rest parameter syntax allows us to represent an indefinite number of arguments as an array. In the example, we use the rest parameters to collect arguments from the second one to the end. We then multiply them by the first one. This example is using an arrow function, which is introduced in the next section.

+ +
function multiply(multiplier, ...theArgs) {
+  return theArgs.map(x => multiplier * x);
+}
+
+var arr = multiply(2, 1, 2, 3);
+console.log(arr); // [2, 4, 6]
+ +

Arrow functions

+ +

An arrow function expression (also known as fat arrow function) has a shorter syntax compared to function expressions and lexically binds the this value. Arrow functions are always anonymous. See also this hacks.mozilla.org blog post: "ES6 In Depth: Arrow functions".

+ +

Two factors influenced the introduction of arrow functions: shorter functions and lexical this.

+ +

Shorter functions

+ +

In some functional patterns, shorter functions are welcome. Compare:

+ +
var a = [
+  "Hydrogen",
+  "Helium",
+  "Lithium",
+  "Beryllium"
+];
+
+var a2 = a.map(function(s){ return s.length });
+
+console.log(a2); // logs [ 8, 6, 7, 9 ]
+
+var a3 = a.map( s => s.length );
+
+console.log(a3); // logs [ 8, 6, 7, 9 ]
+
+ +

Lexical this

+ +

Until arrow functions, every new function defined its own this value (a new object in case of a constructor, undefined in strict mode function calls, the context object if the function is called as an "object method", etc.). This proved to be annoying with an object-oriented style of programming.

+ +
function Person() {
+  // The Person() constructor defines `this` as itself.
+  this.age = 0;
+
+  setInterval(function growUp() {
+    // In nonstrict mode, the growUp() function defines `this`
+    // as the global object, which is different from the `this`
+    // defined by the Person() constructor.
+    this.age++;
+  }, 1000);
+}
+
+var p = new Person();
+ +

In ECMAScript 3/5, this issue was fixed by assigning the value in this to a variable that could be closed over.

+ +
function Person() {
+  var self = this; // Some choose `that` instead of `self`.
+                   // Choose one and be consistent.
+  self.age = 0;
+
+  setInterval(function growUp() {
+    // The callback refers to the `self` variable of which
+    // the value is the expected object.
+    self.age++;
+  }, 1000);
+}
+ +

Alternatively, a bound function could be created so that the proper this value would be passed to the growUp() function.

+ +

Arrow functions capture the this value of the enclosing context, so the following code works as expected.

+ +
function Person(){
+  this.age = 0;
+
+  setInterval(() => {
+    this.age++; // |this| properly refers to the person object
+  }, 1000);
+}
+
+var p = new Person();
+ +

Predefined functions

+ +

JavaScript has several top-level, built-in functions:

+ +
+
{{jsxref("Global_Objects/eval", "eval()")}}
+
+

The eval() method evaluates JavaScript code represented as a string.

+
+
{{jsxref("Global_Objects/uneval", "uneval()")}} {{non-standard_inline}}
+
+

The uneval() method creates a string representation of the source code of an {{jsxref("Object")}}.

+
+
{{jsxref("Global_Objects/isFinite", "isFinite()")}}
+
+

The global isFinite() function determines whether the passed value is a finite number. If needed, the parameter is first converted to a number.

+
+
{{jsxref("Global_Objects/isNaN", "isNaN()")}}
+
+

The isNaN() function determines whether a value is {{jsxref("Global_Objects/NaN", "NaN")}} or not. Note: coercion inside the isNaN function has interesting rules; you may alternatively want to use {{jsxref("Number.isNaN()")}}, as defined in ECMAScript 6, or you can use typeof to determine if the value is Not-A-Number.

+
+
{{jsxref("Global_Objects/parseFloat", "parseFloat()")}}
+
+

The parseFloat() function parses a string argument and returns a floating point number.

+
+
{{jsxref("Global_Objects/parseInt", "parseInt()")}}
+
+

The parseInt() function parses a string argument and returns an integer of the specified radix (the base in mathematical numeral systems).

+
+
{{jsxref("Global_Objects/decodeURI", "decodeURI()")}}
+
+

The decodeURI() function decodes a Uniform Resource Identifier (URI) previously created by {{jsxref("Global_Objects/encodeURI", "encodeURI")}} or by a similar routine.

+
+
{{jsxref("Global_Objects/decodeURIComponent", "decodeURIComponent()")}}
+
+

The decodeURIComponent() method decodes a Uniform Resource Identifier (URI) component previously created by {{jsxref("Global_Objects/encodeURIComponent", "encodeURIComponent")}} or by a similar routine.

+
+
{{jsxref("Global_Objects/encodeURI", "encodeURI()")}}
+
+

The encodeURI() method encodes a Uniform Resource Identifier (URI) by replacing each instance of certain characters by one, two, three, or four escape sequences representing the UTF-8 encoding of the character (will only be four escape sequences for characters composed of two "surrogate" characters).

+
+
{{jsxref("Global_Objects/encodeURIComponent", "encodeURIComponent()")}}
+
+

The encodeURIComponent() method encodes a Uniform Resource Identifier (URI) component by replacing each instance of certain characters by one, two, three, or four escape sequences representing the UTF-8 encoding of the character (will only be four escape sequences for characters composed of two "surrogate" characters).

+
+
{{jsxref("Global_Objects/escape", "escape()")}} {{deprecated_inline}}
+
+

The deprecated escape() method computes a new string in which certain characters have been replaced by a hexadecimal escape sequence. Use {{jsxref("Global_Objects/encodeURI", "encodeURI")}} or {{jsxref("Global_Objects/encodeURIComponent", "encodeURIComponent")}} instead.

+
+
{{jsxref("Global_Objects/unescape", "unescape()")}} {{deprecated_inline}}
+
+

The deprecated unescape() method computes a new string in which hexadecimal escape sequences are replaced with the character that it represents. The escape sequences might be introduced by a function like {{jsxref("Global_Objects/escape", "escape")}}. Because unescape() is deprecated, use {{jsxref("Global_Objects/decodeURI", "decodeURI()")}} or {{jsxref("Global_Objects/decodeURIComponent", "decodeURIComponent")}} instead.

+
+
+ +

{{PreviousNext("Web/JavaScript/Guide/Loops_and_iteration", "Web/JavaScript/Guide/Expressions_and_Operators")}}

diff --git a/files/tr/web/javascript/guide/grammar_and_types/index.html b/files/tr/web/javascript/guide/grammar_and_types/index.html new file mode 100644 index 0000000000..a1619e77aa --- /dev/null +++ b/files/tr/web/javascript/guide/grammar_and_types/index.html @@ -0,0 +1,640 @@ +--- +title: Dil bilgisi ve türler +slug: Web/JavaScript/Guide/Grammar_and_types +tags: + - JavaScript + - Rehber +translation_of: Web/JavaScript/Guide/Grammar_and_types +--- +

{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Introduction", "Web/JavaScript/Guide/Control_flow_and_error_handling")}}

+ +

Bu bölümde JavaScript'in temel dil bilgisi, değişken tanımları, veri türleri ve sabitleri üzerine değinilecektir.

+ +

Temeller

+ +

JavaScript çoğu söz dizimini Java'dan almıştır. Awk, Perl and Python'dan da etkilenmiştir.

+ +

JavaScript büyük-küçük harfe duyarlıdır ve Unicode karakter setini kullanır.

+ +

JavaScript'te, komutlara {{Glossary("Statement", "statements")}} denir ve noktalı virgül (;) ile ayrılırlar. Boşluklara, tablara ve satırbaşı karakterlerine whitespace denir. JavaScript betiklerinde, kaynak metin soldan sağa taranır ve token, kontrol karakterleri, satır sonlayıcıları, yorumlar ve whitespace gibi girdi elemanları dizisine dönüştürülür. ECMAScript, bazı kelimeleri ve sabitleri tanımlamıştır ayrıca noktalı virgül (;) karakterinin komut sonlarına otomatik olarak eklenmesi için kurallar belirlemiştir. Ancak kodda herhangi bir yan etki oluşturmaması için komut sonlarına her zaman noktalı virgül konması önerilir.  Daha fazla bilgi için JavaScript'in sözcük dil bilgisi hakkındaki başvurusuna bakınız.

+ +

Yorumlar

+ +

Yorumların söz dizimi C++ ve çoğu diğer dillerde olduğu şekilde aynıdır:

+ +
// Tek satırlık yorum.
+
+/* *
+ * Bu ise daha uzun,
+ * çok satırlı yorum.
+ */
+
+/* Ancak /* iç içe yorum */  konulması söz dizimi hatasına yol açar */
+ +

Bildirimler

+ +

JavaScript'te üç çeşit bildirim vardır:

+ +

{{jsxref("Statements/var", "var")}}

+ +
+
Bir değişkeni tanımlar, isteğe bağlı olarak değer ataması yapılır.
+
{{experimental_inline}} {{jsxref("Statements/let", "let")}}
+
Etki alanı kod bloğudur, yerel değişken tanımlar, isteğe bağlı olarak değer ataması yapar.
+
{{experimental_inline}} {{jsxref("Statements/const", "const")}}
+
Salt okunur değişken tanımlar.
+
+ +

Değişkenler

+ +

Uygulamalarınızda, verilerin sembolik birer gösterimi olarak değişkenleri kullanırsınız. Değişkenlerin isimine {{Glossary("Identifier", "identifiers")}} denir ve kesin kurallar çerçevesinde oluşturulurlar.

+ +

JavaScript'te değişken adı; bir harfle, alt tire (_) ile veya dolar işareti ($) ile başlamalıdır; ardından rakamlar gelebilir (0-9). JavaScript'in büyük-küçük harfe duyarlı olmasından dolayı, harfler büyük harf (A'dan Z'ye) ve küçük harf (a'dan z'ye) içerebilirler. 

+ +

Değişken adları için å ve ü gibi Unicode harfleri bulunan ISO 8859-1 standardındaki karakter setini kullanabilirsiniz. Ayrıca değişkenlerdeki karakterler olarak, Unicode kaçış karakterlerini kullanabilirsiniz.

+ +

Bir kaç uygun örnek: Popüler_şarkılar, jamesBond007, _isim.

+ +

Değişken tanımlama

+ +

Bir değişkeni üç yolla tanımlayabilirsiniz:

+ + + +

Değişkenlerin değerlendirilmesi

+ +

var veya let komutuyla başlangıç değer ataması yapmadan tanımlanan değişkenler, {{jsxref("undefined")}} değerine sahiptirler.

+ +

Değer ataması yapılmayan bir değişkene erişilmeye çalışıldığında {{jsxref("ReferenceError")}} hatası alınır:

+ +
var a;
+console.log("a'nın değeri " + a); // a'nın değeri undefined
+
+var b;
+console.log("b'nın değeri " + b); // b'nin değeri undefined
+
+console.log("c'nin değeri " + c); // 
+Yakalanmamış Referans Hatası: c değeri tanımlanamadı
+
+let x;
+console.log("x'in değeri " + x); // x'in değeri undefined
+
+console.log("y'in değeri " + y); // 
+Yakalanmamış Referans Hatası: y değeri tanımlanamadı
+let y;
+ +

undefined'ı, bir değişkenin herhangi bir değere sahip olup olmadığını kontrol etmek için kullanabilirsiniz.  Aşağıdaki kod parçasında girdi değişkenine değer atanmamıştır ve if ifadesi doğru olarak değerlendirileceği için bunuYap(); metodu çalıştırılmış olur. 

+ +
var girdi;
+if(girdi === undefined){
+  bunuYap();
+} else {
+  sunuYap();
+}
+
+ +

Eğer undefined değeri boolean bir kontrol deyiminde (if, while vb.) kullanılırsa  yanlış (false) çıktı verecek şekilde davranır . Örneğin, aşağıdaki kodda benimDizim değişkeni tanımsız olduğu için yap() fonksiyonu çalıştırılır:

+ +
var benimDizim = [];
+if (!benimDizim[0]) yap();
+
+ +

Eğer undefined değeri sayısal bir içerikte kullanıldığında NaN (sayı değil) değerini alır.

+ +
var a;
+a + 2;  // NaN sonucunu verir
+ +

{{jsxref("null")}} değişkeni sayısal bir içerikte kullanıldığında 0, boolean bir içerikte kullanıldığında ise false gibi davranır. Örneğin:

+ +
var n = null;
+console.log(n * 32); // ekrana 0 yazdırır
+
+ +

Değişkenin etki alanı

+ +

Herhangi bir fonksiyon etki alanının dışında bir değişken tanımladığınız zaman, global değişken tanımlamış olursunuz. Bu sayede JavaScript dokümanı içerisinde herhangi bir kod parçası bu değişkene erişilebilir. Bir fonksiyon etki alanı içerisinde değişken tanımladığınızda local (yerel)  değişken tanımlamış olursunuz. Bu sayede değişkene sadece o fonksiyon içerisinden erişilebilir.

+ +

ECMAScript 6'dan önceki JavaScript'te, blok seviyesinde etki alanı yoktur; bilâkis, blok içerisinde tanımlanan değişken, o bloğun bulunduğu fonksiyonda (veya global etki alanında) yerel olarak tanımlanmış olur. Örneğin aşağıdaki kod ekrana 5 değerini yazdırır. Çünkü x'in etki alanı, if bloğu içerisinde değil, x'in tanımlandığı fonksiyonda (veya globalde) yer almaktadır.

+ +
if (true) {
+  var x = 5;
+}
+console.log(x);  // 5
+
+ +

ECMAScript 2015'te belirlenen let ifadesi ile kullanılırsa, çıktı değişkenlik gösterebilir. Çünkü let ifadesi global alanı değil if bloğunun alanını etki alanı olarak ele alır ve y değişkeni, JavaScript tarafından tanımsız olarak değerlendirileceği için hata döndürür:

+ +
if (true) {
+  let y = 5;
+}
+console.log(y);  // Uncaught ReferenceError: y is not defined
+
+ +

Değişkeni yukarı alma (hoisting)

+ +

JavaScript'teki değişkenler hakkında bir sıradışı olay ise, tanımladığınız bir değişkene daha önceki satırda hata almadan erişebiliyor olmanızdır. Bu kavram hoisting (yukarı alma) olarak bilinir; JavaScript'te tanımlanan değişkenler bir anlamda fonksiyon veya ifadenin üzerine alınmış (hoisted) olarak ele alınır. Yukarı alınan değişkenler atandıkları değer yerine undefined değerini alırlar. Hatta bu değişkeni kullandıktan sonra tekrar tanımlarsanız, yine undefined sonucunu alırsınız.

+ +
/**
+ * Örnek 1
+ */
+console.log(x === undefined); // "true" yazar
+var x = 3;
+
+/**
+ * Örnek 2
+ */
+// undefined değeri alacak
+var degiskenim = "değerim";
+
+(function() {
+  console.log(degiskenim); // undefined
+  var degiskenim = "yerel değerim";
+})();
+
+ +

Üstteki örnekler bilgisayar tarafından aşağıdaki şekilde yorumlanır:

+ +
/**
+ * Örnek 1
+ */
+var x;
+console.log(x === undefined); // "true" yazar
+x = 3;
+
+/**
+ * Örnek 2
+ */
+var degiskenim = "değerim";
+
+(function() {
+  var degiskenim;
+  console.log(degiskenim); // undefined yazar
+  degiskenim = "yerel değerim";
+})();
+
+ +

Yukarı alma ile ilgili sorunların yaşanmaması için, fonksiyon içerisinde yer alan bütün değişken tanımları olabildiğince en üste taşınmalıdır. Değişken tanımlamanın en iyi yöntemi de zaten budur. Bu sayede kodun okunabilirliği artmış olur. 

+ +

ECMAScript 2015'te, let veya const ifadesi ile tanımlanan değişken, üste alınmaz. Değişken tanımından önce o değişkenin kullanılmaya çalışılırsa {{jsxref("ReferenceError")}} hatası ile sonuçlanır. Değişken, bloğun başlangıcından itibaren tanımının yapıldığı yere kadar ölü bölgededir.

+ +

Fonksiyonu yukarı alma

+ +

Fonksiyonlarda, yalnızca fonksiyon tanımı yukarı alınır. Fonksiyon ifadesine erişilmeye çalışıldığında ise hata oluşur.

+ +
/* fonksiyon tanımlama */
+
+foo(); // "bar"
+
+function foo() {
+  console.log('bar');
+}
+
+
+/* fonksiyon ifadesi */
+
+baz(); // TypeError: baz is not a function
+
+var baz = function() {
+  console.log('bar2');
+};
+
+ +

Global değişkenler

+ +

Global değişkenler aslında temel bir global nesnenin özellikleridirler. Web sayfalarında bulunan global nesnenin adı {{domxref("window")}} 'dur. Böylece global değişkenlere, window.variable söz dizimi kullanılarak erişilebilir.

+ +

Sonuç olarak, herhangi bir window veya iframe'deki global değişkenlere, diğer window veya iframe üzerinden değişkenin ismi kullanılarak erişilebilir. Örneğin, eğer bir dokümanda telefonNumarası isminde bir değişken tanımlanmışsa, bu değişkene iframe içerisinden parent.telefonNumarası şeklinde erişebilirsiniz.

+ +

Sabitler

+ +

{{jsxref("Statements/const", "const")}} anahtar kelimesi ile sabit bir değişken oluşturabilirsiniz. Sabit değerler için söz dizimi, değişken değerleri ile aynıdır: bir harf, alt çizgi veya dolar işareti ile başlamalıdırlar, devamında ise alfabetik, sayısal veya alt çizgi gibi karakterler gelebilir.

+ +
const PI = 3.14;
+ +

JavaScript kodu çalışırken bir sabitin değeri, atama yapılarak değiştirilemez ve sabit tekrar tanımlanamaz. Ayrıca sabitlere başlangıçta tanımlanırken bir değer atanması zorunludur.

+ +

Sabitlerin etki alanı let bloğunun etki alanındaki değişkenler ile aynıdır. Eğer const ifadesi çıkarılırsa, ifade artık değişken haline gelir.

+ +

Bir etki alanında, halihazırda bir fonksiyon veya değişken varsa, aynı isimli sabit tanımlamak hataya yol açar. Örneğin:

+ +
// BU HATAYA NEDEN OLUR
+function f() {};
+const f = 5;
+
+// BU DA HATAYA NEDEN OLUR
+function f() {
+  const g = 5;
+  var g;
+}
+
+ +

Sabit bir nesneye atanan özellikler diğer fonksiyonların kullanımına karşı korunmamışlardır ve nesnenin kendisi sabit olmasına rağmen değişken değerler alabilirler. Bu sebeple aşağıdaki ifade sorunsuz bir şekilde çalışır.

+ +
const BENIM_NESNEM = {"anahtar": "değer"};
+BENIM_NESNEM.anahtar = "diğerDeğer";
+ +

Veri yapıları ve tipleri

+ +

Veri tipleri

+ +

Son yayınlanan ECMAScript standardı ile yedi veri tipi tanımlanabilir:

+ + + +

Veri tipleri nispeten az miktarda olmalarına rağmen, uygulamalarınızla yararlı işlevler oluşturmanıza olanak sağlarlar. {{jsxref("Object", "Objects")}} (nesneler) ve {{jsxref("Function", "functions")}} (fonksiyonlar) dilin diğer temel elemanlarıdırlar. Nesneleri, değerleriniz için isimlendirilmiş kutular, fonksiyonları (functions) ise uygulamanızın gerçekleştirebileceği işlevler olarak düşünebilirsiniz.

+ +

Veri tipi dönüşümü

+ +

JavaScript dinamik tipli bir dildir. Bunun anlamı, bir değişken tanımlarken, veri tipini belirtme zorunluluğunuzun olmaması ve değişkenin veri tipinin çalışma esnasında ihtiyaç olunan tipe otomatik olarak dönüştürülmesidir. Örneğin sayısal bir değişken tanımlayabilirsiniz:

+ +
var yanit = 42;
+
+ +

Ve sonra, aynı değişkene string bir değer atayabilirsiniz:

+ +
yanit = "Hoşçakal, balık için teşekkürler...";
+
+ +

JavaScript dinamik tipli olduğu için, bu atama bir hata vermez.

+ +

Bir string ve sayının toplama işlemine konulması ile JavaScript otomatik olarak sayısal değeri string ifadeye çevirir ve eklenecek string ile birleştirir. Örneğin aşağıdaki ifadelere bakalım:

+ +
x = "Cevap " + 42 // "Cevap 42"
+y = 42 + " cevaptır." // "42 cevaptır."
+
+ +

Toplama işlemi dışındaki diğer işlemlerde JavaScript otomatik olarak tür dönüşümü yapmaz. Örneğin:

+ +
"37" - 7 // 30
+"37" + 7 // "377"
+
+ +

String ifadelerin sayısal değerlere dönüştürülmesi

+ +

Bellekte sayısal bir ifadeyi temsil eden bir string'in olduğu durumlarda tip dönüşümü yapmak için aşağıdaki metodları kullanabilirsiniz: 

+ + + +

parseInt fonksiyonu sadece tam sayı döndürür, bu yüzden ondalık sayılarla kullanıldığında ondalık kısmını atar. Buna ek olarak parseInt'in en uygun kullanımlarından biri de sayının hangi tabanda (2'lik, 10'luk, 16'lık vb.) yazılabileceğini parametre olarak fonksiyona verebilmenizdir. Taban parametresi hangi sayısal sistemin kullanılacağının belirlenmesini sağlar.

+ +

String ifadelerin, sayısal ifadelere dönüştürülmesinin diğer bir yolu da, string ifadenin başına + operatörünün eklenmesidir:

+ +
"1.1" + "1.1" = "1.11.1"
+(+"1.1") + (+"1.1") = 2.2
+// Not: parantezler gösterim kolaylığı için konulmuştur, zorunlu değildir.
+ +

Değişken değerleri

+ +

JavaScript'te değişkenlerin temsil edilmesi için değerler kullanırsınız. Bunlar, kodunuzda değişkenlere = operatöründen sonra atadığınız değerlerdir. Bu kısımda aşağıdaki değer tiplerini inceleyeceğiz:

+ + + +

Dizi değerleri

+ +

Bir dizi değeri 0 veya daha fazla ifadeden oluşan liste biçimindedir, liste başında ve sonunda listeyi açıp/kapatan köşeli parantezler [ ] bulunur. Bir dizi oluşturup bu diziye değerler atadığınızda, belirlediğiniz değerleri kendi elemanı olarak barındıran bir dizi üretilir ve dizinin uzunluğu belirlediğiniz değer sayısı kadardır.

+ +

Aşağıdaki örnekte, 3 elemanı barındıran ve bu nedenle 3 uzunluğunda olan kahveler isimli bir dizi oluşturulmaktadır:

+ +
var kahveler = ["Türk kahvesi", "Espresso", "Mocha"];
+
+ +
+

Not : Bir dizi değeri, bir nesne başlatıcısı türündedir. Dahası için bkz: Nesne başlatıcılarının kullanımı.

+
+ +

Eğer bir dizi, üst-seviye betikte sabit değer kullanarak oluşturulmuşsa JavaScript, bu diziyi içeren her ifadeyi çalıştırdığında diziyi yorumlar. Buna ek olarak, fonksiyon içerisinde tanımlanan diziler, her fonksiyon çağrımında yeni bir dizi olarak bellekte oluşturulur.

+ +

Dizi değerleri ayrıca Array nesneleridirler. Detaylı bilgi için {{jsxref("Array")}} ve Index'li koleksiyonlar kısmına bakınız.

+ +

Dizi değerleri arasında bulunan fazladan virgül

+ +

Dizi tanımlarken her değeri belirlemek zorunda değilsiniz. Eğer iki tane virgülü art arda koyarak dizi oluşturursanız, virgüller arasında kalan tanımlanmayan her değer için undefined değeri üretilir. Aşağıdaki örnekte bir balık dizisi oluşturulmaktadır:

+ +
var balik = ["Japon", , "Melek"];
+
+ +

Bu dizi değerlere sahip 2 elemana ve bir tane boş elemana sahiptir (balik[0] = "Japon", balik[1]undefined, ve balik[2] = "Melek").

+ +

Eğer dizideki elemanların sonuna virgül koyarsanız virgül, JavaScript tarafından görmezden gelinir. Aşağıdaki örnekte bulunan dizinin uzunluğu üçtür. dizi[3]'ü ifade eden herhangi bir eleman bulunmamaktadır. Listedeki diğer virgüller, undefined değerine sahip yeni bir elemanı ifade eder. 

+ +
+

Not : Sona konan virgüller, eski versiyonlu tarayıcılarda hatalara neden olur. Yapılacak en doğru şey, dizi sonlarında kullanılan virgüllerin kaldırılmasıdır.

+
+ +
var dizi = ['ev', , 'okul', ];
+
+ +

Aşağıdaki örnekte oluşturulan dizinin uzunluğu, dizi[0] ve dizi[2] değerleri tanımlanmadığı halde 4'tür.

+ +
var dizi = [ , 'ev', , 'okul'];
+
+ +

Aşağıdaki bir diğer örnekte, dizinin uzunluğu, dizi[1] ve dizi[3] değerleri tanımlanmadığı halde yine 4'tür. Sadece son virgül görmezden gelinir.

+ +
var dizi = ['ev', , 'okul', , ];
+
+ +

Ekstra virgüllerin davranışlarının kavranılması, JavaScript dilinin öğrenilmesi için çok önemlidir, ancak kendi kodunuzu yazarken tanımsız elemanları undefined olarak dizi içerisinde belirlemeniz, kodunuzun okunabilirliğini ve bakım yapılabilirliğini önemli ölçüde arttıracaktır.

+ +

Boolean değerleri

+ +

Boolean tipinde iki çeşit değer bulunur: true (doğru) ve false (yanlış).

+ +

İlkel Boolean değerleri olan true ve false ile Boolean nesnesi olan true ve false değerlerini karıştırmayınız. Boolean nesnesi, ilkel olan Boolean veri tipinin alınması ve üzerine bazı ek özellikler getirilmesi ile oluşturulmuştur. Daha fazlası için bkz: {{jsxref("Boolean")}}.

+ +

Tam sayılar

+ +

Tam sayılar; ikilik (binary) (2 tabanında), sekizlik (octal) (8 tabanında), onluk (decimal) (10 tabanında), ve onaltılık (hexadecimal) (16 tabanında) temsil edilebilirler.

+ + + +

Bazı örnek tamsayılar:

+ +
0, 117 and -345 (onluk, 10 tabanında)
+015, 0001 and -077 (sekizlik, 8 tabanında)
+0x1123, 0x00111 and -0xF1A7 (onaltılık, "hex" veya 16 tabanında)
+0b11, 0b0011 and -0b11 (ikilik, 2 tabanında)
+
+ +

Daha fazlası için bkz: Sayısal değerler ve sözsel gramer başvurusu.

+ +

Ondalıklı değerler

+ +

Bir ondalıklı değer aşağıdaki kısımları içerebilir:

+ + + +

Katsayı kısmı  bir "e" veya "E" karakteridir ve devamında işaretli olabilen bir tamsayı gelir. Ondalıklı değerin tanımlanabilmesi için en az bir rakam ve devamında ondalıklı sayı ve katsayı "e" (veya "E") içermelidir.

+ +

Özetle söz dizimi aşağıdaki şekildedir:

+ +
[(+|-)][rakamlar][.rakamlar][(E|e)[(+|-)]rakamlar]
+
+ +

Örneğin:

+ +
3.1415926
+-.123456789
+-3.1E+12
+.1e-23
+
+ +

Nesne değerleri

+ +

Bir nesne değeri, süslü parantezlerle {} çevrili sıfır veya daha fazla özellik ismi ve bu özellikler ile ilişkili değerleri içeren bir listeden oluşur. Bir kod satırının başlangıcında değişken ismi olmadan sadece süslü parantezler ile başlayarak bir nesne oluşturmamanız gerekmektedir. Eğer oluşturursanız, JavaScript nesne başlangıcındaki { karakterini, bir kod bloğuna başlangıç yapılıyormuş gibi yorumlar ve bunun sonucunda ya bir hata mesajı alırsınız, ya da yazdığınız kod beklediğiniz şekilde çalışmaz.

+ +

Aşağıda, nesne değerini içeren bir örnek bulunmaktadır. otoGaleri nesnesinin ilk elemanı, "Fiat" değerini barındıran arabam isminde bir özelliği tanımlamaktadır; ikinci elemanı arabaAl özelliğidir ve function (arabaTipleri("Honda")) fonksiyonu çalıştırıldıktan hemen sonra fonksiyonun sonucunu içerir; üçüncü eleman sporArabaAl özelliğidir, halihazırda varolan hayalimdekiAraba değişkenini kullanır.

+ +
var hayalimdekiAraba = "Bugatti";
+
+function arabaTipleri(markaAdı) {
+  if (markaAdı == "Wolksvagen") {
+    return markaAdı;
+  } else {
+    return "Üzgünüz, malesef " + markaAdı + " marka araba elimizde bulunmamaktadır.";
+  }
+}
+
+var otoGaleri = {
+    arabam: "Fiat",
+    arabaAl: arabaTipleri("Wolksvagen"),
+    sporArabaAl: arabaTipleri(hayalimdekiAraba)
+};
+
+console.log(otoGaleri.arabam);   // Fiat
+console.log(otoGaleri.arabaAl);  // Wolksvagen
+console.log(otoGaleri.sporArabaAl); // Üzgünüz, malesef Bugatti marka araba elimizde bulunmamaktadır.
+
+ +

Ek olarak, sayısal veya string bir değer, özellik adı veya iç içe olan diğer bir nesnenin adı yerine kullanabilir. Aşağıdaki örnekte bu seçenekleri görebiliriz:

+ +
var otoGaleri = {
+    arabalar: {s: "Saab", "j": "Jeep"},
+    7: "Mazda"
+};
+
+console.log(otoGaleri.arabalar.j); // Jeep
+console.log(otoGaleri[7]); // Mazda
+
+ +

Nesne özelik adları boş bir string de dahil olmak üzere herhangi bir string ifade olabilirler. Eğer özellik adı geçerli bir JavaScript {{Glossary("Identifier","identifier")}} değilse, tırnak içinde yazılması gereklidir. Buna ek olarak geçersiz olan özellik adlarına, nokta (.) ile erişim yapılamaz, bunun yerine dizi tarzında köşeli parantezler([]) kullanılır:

+ +
var geçersizÖzellikAdlarıÖrnek = {
+  "": "Boş bir string",
+  "!": "Ateş!"
+}
+console.log(geçersizÖzellikAdlarıÖrnek."");   // SyntaxError: Unexpected string
+console.log(geçersizÖzellikAdlarıÖrnek[""]);  // Boş bir string
+console.log(geçersizÖzellikAdlarıÖrnek.!);    // SyntaxError: Unexpected token !
+console.log(geçersizÖzellikAdlarıÖrnek["!"]); // Ateş!
+ +

Diğer örnekler:

+ +
var nesne = {a: "armut", 2: "iki"};
+console.log(nesne.a);    // armut
+console.log(nesne[2]);   // iki
+//console.log(nesne.2);  // Error: missing ) after argument list
+//console.log(nesne[a]); // Error: a is not defined
+console.log(nesne["a"]); // armut
+console.log(nesne["2"]); // iki
+
+ +

Düzenli İfade (RegExp) değerleri

+ +

Bir düzenli ifade değeri bölü (/) karakterleri arasında ifade edilir. Aşağıda, örnek bir düzenli ifade bulunmaktadır:

+ +
var re = /ab+c/;
+ +

String değerleri

+ +

Bir string değer çift tırnak (") veya tek tırnak (') arasında bulunan sıfır veya daha fazla karakterlerin yer almasıyla oluşur. Bir string değer aynı tip tırnak ile sonlanmalıdır; bu nedenle karakterleri kapsayan tırnaklar ya çift tırnak ya da tek tırnak ikililerinden oluşmalıdır. Aşağıdaki örnekte string değerler ifade edilmiştir:

+ +
"elma"
+'armut'
+"1234"
+"bir satır \n diğer satır"
+"Zafer'in kedisi"
+
+ +

String nesnesinin herhangi bir fonksiyonuna, string değerin sonuna nokta koyarak erişebilir ve çalıştırabilirsiniz—JavaScript otomatik olarak string değeri geçici bir String nesnesine dönüştürür, metodu çağırır, ve sonra oluşan geçici String nesnesini hafızadan siler. Ayrıca String.length özelliğini de string değerinin sonuna .length ekleyerek kullanablirsiniz:

+ +
console.log("Zafer'in kedisi".length);
+// Boşluk da dahil olmak üzere, string içerisindeki tüm sembollerin sayısını ekrana yazar.
+// Ekrana yazılan değer: 15
+
+ +

String nesnesine hususi olarak ihtiyaç duymadığınız durumlarda, string değerleri kullanmanız gerekir. String nesneler için bkz: {{jsxref("String")}}.

+ +

Özel karakterlerin string değerlerde kullanımı

+ +

String değerler oluştururken, her zamanki kullandığınız karakterlere ek olarak aşağıdaki şekilde özel karakterler de kullanabilirsiniz:

+ +
"bir satır \n diğer satır"
+
+ +

Aşağıdaki tabloda, JavaScript string değerleri içerisinde kullanabileceğiniz özel karakterler listelenmiştir: 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Tablo: JavaScript özel karakterleri
KarakterAnlamı
\0Boş değer
\bGeri silme
\fForm beslemesi
\nYeni satır
\rEnter karakteri
\tTab
\vDikey tab
\'Kesme işareti veya tek tırnak
\"Çift tırnak
\\Ters bölü (\) karakteri
\XXX3 adet sekizlik rakamı barındırabilen, ve 0-377 arasındaki XXX değerlerinin Latin-1 kodlaması ile oluşturulduğu karakterdir. Örneğin, sekizlik \251 değeri telif hakkı sembolünü (©) ifade eder.
\xXX +

2 adet onaltılık karakteri barındırabilen ve 00-FF arasındaki XX değerlerinin Latin-1 kodlaması ile oluşturduğu karakterdir. Örneğin, onaltılık \xA9 değeri telif hakkı sembolünü (©) ifade eder.

+
\uXXXX +

4 adet onaltılık karakteri barındırabilen XXXX değerleri ile belirlenen Unicode karakteridir. Örneğin \u00A9 karakteri, Unicode olarak telif hakkı sembolünü (©) ifade eder. Bkz: Unicode kaçış karakterleri.

+
\u{XXXXX}Unicode kod noktası kaçış karakterlerini ifade eder. Örneğin, \u{2F804} karakteri, \uD87E\uDC04 ile aynı sembolü ifade eder.
+ +

Kaçış karakterleri

+ +

Üstteki tabloda yer almayan karakterlerin başına ters bölü işaretinin konulduğunda, ters bölü işareti göz ardı edilir, fakat bu tarz kullanım artık rafa kaldırılmıştır ve kullanımından kaçınılması gerekir. 

+ +

Bir string değer içerisinde tırnak işaretini kullanabilmeniz için, karakterin başına ters bölü işareti eklemeniz gerekir. Bu kullanıma tırnaktan kaçış (escaping the quotation mark) denir. Örneğin:

+ +
var alıntı = "Sebahattin Ali'nin \"Kürk Mantolu Madonna\" adlı kitabını okudu.";
+console.log(alıntı);
+
+ +

Ekran çıktısı aşağıdaki gibi olacaktır:

+ +
Sebahattin Ali'nin "Kürk Mantolu Madonna" adlı kitabını okudu.
+
+ +

String değer içerisinde ters bölü işaretini kullanabilmeniz için, tekrar bir ters bölü karakteri daha eklemeniz gerekir. Örneğin c:\temp isimli dosya yolunu, bir string olarak aşağıdaki şekilde ifade edebiliriz:

+ +
var geçiciDosyalarDizini = "c:\\temp";
+
+ +

Uzun string değerleri satır satır yazmak için tırnak artı tırnak (" + ") işaretleri ile eklemek yerine satır sonuna sadece ters bölü işareti ekleyebilirsiniz. Ters bölü ve satır sonu karakterleri, string değerinden çıkarılmış olarak tek satır halinde döndürülür.

+ +
var metin = "Bu metin \
+birçok \
+satıra ayrılarak \
+oluşturulmuştur."
+console.log(metin);  // Ekran çıktısı: Bu metin birçok satıra ayrılarak oluşturulmuştur.
+
+ +

JavaScript'in paragrafları tanımlamak için bir söz dizimi bulunmamasına rağmen, her satır sonuna  \n\ karakterleri ekleyerek paragraf oluşturabilirsiniz:

+ +
var şiir =
+"Sana gitme demeyeceğim \n\
+Ama gitme Lavinia \n\
+Adını gizleyeceğim \n\
+Sen de bilme Lavinia.";
+
+ +

Daha fazlası

+ +

Bu bölümde, tanımlamalar ve türler için temel söz dizimleri konuları üzerinde durulmuştur. JavaScript'in dil oluşturucularıyla ilgili daha fazla bilgi edinmek için bu rehberde bulunan aşağıdaki bölümleri inceleyebilirsiniz:

+ + + +

Sonraki bölümde, kontrol akışının oluşturulması ve hata yakalamaya göz atacağız.

+ +

{{PreviousNext("Web/JavaScript/Guide/Introduction", "Web/JavaScript/Guide/Control_flow_and_error_handling")}}

diff --git a/files/tr/web/javascript/guide/ifadeler/index.html b/files/tr/web/javascript/guide/ifadeler/index.html new file mode 100644 index 0000000000..dcf6d13466 --- /dev/null +++ b/files/tr/web/javascript/guide/ifadeler/index.html @@ -0,0 +1,419 @@ +--- +title: Kontrol akışı ve hata yakalama +slug: Web/JavaScript/Guide/Ifadeler +tags: + - Başlangıç + - JavaScript + - Rehberi +translation_of: Web/JavaScript/Guide/Control_flow_and_error_handling +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Grammar_and_types", "Web/JavaScript/Guide/Loops_and_iteration")}}
+ +

JavaScript, uygulamanızın etkilişim halinde olmasını sağlayan kontrol akışı ifadeleri gibi birçok ifadeyi destekler. Bu bölümde, bu ifadeler üzerine durulacaktır.

+ +

En basit olarak anlatmak gerekirse, JavaScript tarafından çalıştırılacak her komuta ifade adı verilir. Noktalı virgül (;) karakteri ise, JavaScript kodundaki ifadelerin birbirinden ayrılması için kullanılmaktadır.

+ +

Blok ifadesi

+ +

En temel ifade türü, ifadelerin gruplanmasını sağlayan blok ifadesidir. Blok ifadesi,  bir çift süslü parantezle sınırlandırılır:

+ +
{ ifade_1; ifade_2; . . . ifade_n; }
+
+ +

Örnek

+ +

Blok ifadeleri genellikle kontrol akışı ifadeleri ile birlikte kullanılır (örn: if, for, while).

+ +
while (x < 10) {
+  x++;
+}
+
+ +

Buradaki, { x++; } bir blok ifadesidir.

+ +

Önemli: ECMAScript2015'ten önceki JavaScript'te blok etki alanı bulunmamaktadır. Blok içerisinde yer alan değişkenlerin etki alanı, onları içeren fonksiyon veya .js dosyası kadar geniş bir alanı kapsar, ve bu değişkenler üzerinde yapılan değişiklikler bloğun ötesinde de kalıcılık gösterir. Başka bir deyişle blok ifadeleri, değişkenler için bir etki alanı oluşturmazlar. C ve Java dilinden aşina olduğunuz değişkenden bağımsız blok ifadeleri, JavaScript'te tamamıyla farklı bir davranış sergileyebilirler. Aşağıdaki örneği inceleyelim:

+ +
var x = 1;
+{
+  var x = 2;
+}
+console.log(x); // Ekrandaki çıktı: 2
+
+ +

Kodun çıktısı 2 olacaktır. Çünkü blok içerisindeki var x ifadesi  ile bloktan önce gelen var x ifadesi aynı etki alanı içerisindedir. Eğer üstteki kod C veya Java dilinde olsaydı, ekrandaki çıktı 1 olacaktı.

+ +

ECMAScript 6 ile birlikte gelen let tanımıyla oluşturulan değişkenler, blok seviyesinde etki alanına sahiptir. Daha fazla bilgi için {{jsxref("Statements/let", "let")}} sayfasına bakınız.

+ +

Koşullu ifadeler

+ +

Belirli bir koşul sağlandığında çalışacak komutlar kümesine koşullu ifade denilir. JavaScript, iki adet koşullu ifadeyi destekler: if...else ve switch.

+ +

if...else ifadesi

+ +

Belirli bir mantıksal durum sağlandığında bir ifadenin çalıştırılması için if ifadesi kullanılır. Mantıksal durum sağlanmadığında çalıştırılacak komutlar için ise else kelimesi kullanıılabilir. Bir if ifadesi aşağıdaki şekilde oluşturulur:

+ +
if (mantıksal_durum) {
+  ifade_1;
+} else {
+  ifade_2;
+}
+ +

mantıksal_durum, true veya false değerler alabilen herhangi bir ifade olabilir. Eğer mantıksal_durum, true olursa ifade_1 çalışacak; aksi halde, ifade_2 is çalışacaktır. ifade_1 ve ifade_2 ifadeleri, çalıştırılacak herhangi bir ifade olabilir.

+ +

Birçok mantıksal durumun kontrolünün bütün bir halde yapılabilmesi için aşağıdaki şekilde else if tanımlamalarını kullanabilirsiniz.

+ +
if (mantıksal_durum_1) {
+  ifade_1;
+} else if (mantıksal_durum_2) {
+  ifade_2;
+} else if (mantıksal_durum_n) {
+  ifade_n;
+} else {
+  ifade_son;
+}
+
+ +

Üstteki gibi çoklu mantıksal durumların olduğu ifadelerde,  yalnızca true olan ilk mantıksal durum çalıştırılır, ilişkili diğer kontrol ifadeleri çalıştırılmaz. Birçok ifadenin çalıştırılması için ifadeler, blok ifadesi ({ ... }) içerisinde gruplandırılır. Özellikle iç içe if ifadelerinin olduğu durumlar başta olmak üzere blok ifadeleri, geliştiriciler arasında yaygın olarak kullanılmaktadır:

+ +
if (mantıksal_durum) {
+  eğer_durum_true_ise_çalışacak_ifade_1;
+  eğer_durum_true_ise_çalışacak_ifade_2;
+} else {
+  eğer_durum_false_ise_çalışacak_ifade_3;
+  eğer_durum_false_ise_çalışacak_ifade_4;
+}
+
+ +
mantıksal_durum kısmında herhangi bir değişkene değer atamak yanlış bir kullanımdır, çünkü kodunuza sizden sonra bakan biri atama işlemini ilk bakışta eşitlik olarak görebilir. Örneğin aşağıdaki şekilde bir kullanım yanlıştır:
+ +
+ +
if (x = y) {
+  /* diğer ifadeler */
+}
+
+ +

Eğer mantıksal_durum kısmında gerçekten atama yapmanız gerekiyorsa, bunu yapmanın en iyi yolu atama ifadesini parantezler içerisine almaktır. Örneğin:

+ +
if ((x = y)) {
+  /* diğer ifadeler */
+}
+
+ +

Yanlışımsı (falsy) değerler

+ +

Aşağıdaki değerler JavaScript tarafından false olarak değerlendirilir ve ({{Glossary("Falsy")}} değerler olarak bilinir):

+ + + +

Mantıksal durum içerisine alınan diğer bütün değerler ve nesneler, JavaScript tarafından true olarak değerlendirilir.

+ +

{{jsxref("Boolean")}} nesnesindeki true ve false ile ilkel tipteki true ve false değerlerini karıştırmayınız. Örneğin:

+ +
var b = new Boolean(false);
+if (b) // bu ifade true olarak değerlendirilir
+
+ +

Örnek

+ +

Aşağıdaki örnekte bulunan checkData fonksiyonu, HTML dokümanındaki formda yer alan ikiKarakter isimli girdi nesnesine ait değerin, karakter sayısı 2 ise true döndürülür, değilse ekrana bir uyarı metni basılır ve false döndürülür:

+ +
function checkData() {
+  if (document.form1.ikiKarakter.value.length == 2) {
+    return true;
+  } else {
+    alert("Tam olarak iki karakter giriniz. " +
+    document.form1.ikiKarakter.value + " geçersizdir.");
+    return false;
+  }
+}
+
+ +

switch ifadesi

+ +

Bir switch ifadesine, mantıksal bir ifade verilir ve bu ifade ile eşleşen bir etiket varsa, etiketi içeren case ifadesi çalıştırılır, yoksa varsayılan ifade (default) çalıştırılır. Örnek:

+ +
switch (mantıksal_ifade) {
+  case etiket_1:
+    ifadeler_1
+    [break;]
+  case etiket_2:
+    ifadeler_2
+    [break;]
+    ...
+  default:
+    varsayılan_ifadeler
+    [break;]
+}
+
+ +

Üstteki kodu çalıştırırken JavaScript, mantıksal_ifade ile eşleşen etikete sahip case cümleciğini arar ve ilişkili ifadeleri çalıştırır. Eğer eşleşen hiçbir etiket bulunamadıysa, default cümleciğinin olup olmadığına bakar, varsa ve ilgili varsayılan ifadeleri çalıştırır. Eğer default cümleciği de yoksa, switch bloğundan çıkılır.  default cümleciğinin sırası önemli olmamakla birlikte, genel kullanımlarda hep en sonda yer almaktadır.

+ +

Her case cümleciğinde, isteğe bağlı olarak konulan break ifadesi,  eşleşen ifadenin çalıştırılıp tamamlandıktan sonra switch bloğundan çıkmayı sağlar. Eğer break ifadesi yazılmazsa, program switch ifadesi içerisindeki bir sonraki case ifadesini çalıştırarak yoluna devam eder. 

+ +

Örnek

+ +

Aşağıdaki örnekte, meyve ifadesinin değeri "Muz" ise,  program "Muz" değeri ile eşleşen case "Muz" ifadesini çalıştırır. break ile karşılaşıldığında, program switch bloğundan çıkar ve switch bloğundan sonraki kodları çalıştırır. Eğer break ifadesi olmasaydı, "Muz" ile alakasız olan, case "Kiraz" ifadesi de çalıştırılacaktı.

+ +
switch (meyve) {
+  case "Portakal":
+    console.log("Portakalların kilosu ₺1.99 lira.");
+    break;
+  case "Elma":
+    console.log("Elmaların kilosu ₺1.49 lira.");
+    break;
+  case "Muz":
+    console.log("Muzların kilosu ₺2.49 lira.");
+    break;
+  case "Kiraz":
+    console.log("Kirazların kilosu ₺2.19 lira.");
+    break;
+  case "Çilek":
+    console.log("Çileklerin kilosu ₺2.49 lira.");
+    break;
+  case "Avokado":
+    console.log("Avokadoların kilosu ₺5.99 lira.");
+    break;
+  default:
+   console.log("Maalesef elimizde hiç " + meyve + " kalmadı.");
+}
+console.log("Başka bir şey lazım mı?");
+ +

Exception (Hata) yakalama ifadeleri

+ +

throw ifadesi ile exception fırlatabilir, try...catch ifadeleri kullanarak hata yakalama işlemlerinizi yürütebilirsiniz.

+ + + +

Exception türleri

+ +

JavaScript'te neredeyse her nesne fırlatılabilir. Buna rağmen fırlatılacak türdeki nesnelerin hepsi aynı şekilde oluşturulmamışlardır. Sayı ve string değerlerinin hata olarak fırlatılması oldukça yaygın olmasına rağmen, bu amaç için belirli olarak  oluşturulan aşağıdaki exception türlerinden birinin kullanılması daha anlamlıdır:

+ + + +

throw ifadesi

+ +

Bir exception fırlatmak için throw ifadesini kullanılır. Bir exception fırlattığınız zaman, fırlatılacak ifadeyi de belirlersiniz:

+ +
throw ifade;
+
+ +

Herhangi bir türdeki ifadeyi exception olarak fırlatabilirsiniz. Aşağıdaki kodda çeşitli türlerdeki exception'lar fırlatılmaktadır:

+ +
throw "Hata2";   // String türü
+throw 42;         // Sayı türü
+throw true;       // Boolean türü
+throw { toString: function() { return "Ben bir nesneyim."; } };
+
+ +
Not: Bir exception fırlatırken ilgili exception nesnesini belirleyebilirsiniz. Daha sonra catch bloğunda hatayı yakaladığınızda ilgili exception nesnesinin özelliklerine erişebilirsiniz. Aşağıdaki ifadede, KullanıcıHatası sınıfından bir nesne oluşturulmakta, ve throw ifadesinde bu nesne fırlatılmaktadır.
+ +
// KullanıcıHatası türünde nesne oluşturuluyor
+function KullanıcıHatası(mesaj){
+  this.mesaj=mesaj;
+  this.adı="KullanıcıHatası";
+}
+
+// Oluşturulan KullanıcıHatası nesnesinin konsola yazıldığında güzel bir
+// ifade yazılması için aşağıdaki şekilde toString() fonksiyonunu override ediyoruz.
+KullanıcıHatası.prototype.toString = function () {
+  return this.adı+ ': "' + this.mesaj+ '"';
+}
+
+// KullanıcıHatası nesnesi yaratılır ve exception olarak fırlatılır
+throw new KullanıcıHatası("Yanlış bir değer girdiniz.");
+ +

try...catch ifadesi

+ +

try...catch ifadesi, çalıştırılması istenen ifadeleri bir blokta tutar. Fırlatılacak exception için bir veya daha fazla ifade belirlenerek, oluşacak bir try...catch ifadesi tarafından yakalanması sağlanır.

+ +

try...catch ifadesi, çalıştırılacak bir veya daha fazla komutun yer aldığı, ve try bloğu içerisinde hata oluştuğunda çalışacak ifadeleri içeren, 0 veya daha fazla catch ifadesinin yer aldığı bir try bloğu içerir. Bu şekilde, try içerisinde yer alan başarıyla çalışmasını istediğiniz kodlarda bir sorun oluştuğunda, catch bloğunda bu sorunun üstesinden gelecek kontrolleri yazabilirsiniz. Eğer try bloğu içerisindeki herhangi bir ifade (veya try bloğu içerisinden çağırılan fonksiyon) bir exception fırlatırsa, JavaScript anında catch bloğuna bakar. Eğer try bloğu içerisinde bir exception fırlatılmazsa, catch bloğu çalıştırılmaz ve atlanır. try ve catch bloklarından sonra, eğer varsa finally bloğu da çalıştırılır.

+ +

Aşağıdaki örnekte bir try...catch ifadesi kullanılmaktadır. Fonksiyonda, parametre olarak geçilen ay sayısı değeri baz alınarak, diziden ilgili ayın adı getirilmektedir. Eğer ay sayısı değeri 1-12 arasında değilse, "Geçersiz ay sayısı." değeri exception olarak fırlatılır. catch bloğundaki ayAdı değişkeni de "bilinmeyen" olarak atanır.

+ +
function getAyAdı(aySayisi) {
+  aySayisi= aySayisi-1; // Dizi indeksi için aySayisi 1 azaltılır (1=Oca, 12=Ara)
+  var aylar= ["Oca","Şub","Mar","Nis","May","Haz","Tem",
+                "Ağu","Eyl","Eki","Kas","Ara"];
+  if (aylar[aySayisi] != null) {
+    return aylar[aySayisi];
+  } else {
+    throw "Geçersiz ay sayısı."; // burada throw ifadesi kullanılıyor
+  }
+}
+
+try { // denenecek ifadeler
+  ayAdı = getAyAdı(aySayim); // function could throw exception
+}
+catch (e) {
+  ayAdı = "bilinmiyor";
+  hatalarımıKaydet(e); // hataların kaydedilmesi için exception nesnesi geçiliyor.
+}
+
+ +

catch bloğu

+ +

try bloğunda oluşturulan tüm exception'ların yakalanması için catch bloğunu kullanabilirsiniz.

+ +
catch (exceptionDeğişkeni) {
+  ifadeler
+}
+
+ +

catch bloğunda, throw ifadesi tarafından belirlenecek değerin tutulması için bir değişken tanımlanır; bu değişken kullanılarak, fırlatılan exception ile ilgili bilgiler elde edilmiş olur. catch bloğuna girildiğinde JavaScript, bu değişkenin içini doldurur; değişken değeri sadece catch bloğu süresince geçerli kalır; catch bloğu çalışmasını tamamladığında değişken artık mevcut değildir.

+ +

Örneğin aşağıdaki kodda, bir exception fırlatılıyor, ve fırlatıldığı anda otomatik olarak catch bloğuna iletiliyor.

+ +
try {
+  throw "hata" // bir exception oluşturur.
+}
+catch (e) {
+  // herhangi bir exception'ı yakalamak için oluşturulan ifadeler
+  hatalarımıKaydet(e) // hataların kaydedilmesi için exception nesnesi geçilir.
+}
+
+ +

finally bloğu

+ +

finally bloğu, try...catch ifadesinden sonra çalıştırılacak kod satırlarını içerir. finally bloğu, hata olsun veya olmasın çalışır. Eğer hata olmuşsa ve exception fırlatılmışsa, bu hatayı karşılayacak catch bloğu olmasa dahi finally bloğu çalışır. 

+ +

finally bloğu, hata oluştuğunda bu hataya sebep olan değişkenin kullandığı kaynakların sisteme geri verilmesi için en iyi yerdir. Bu şekilde hata tüm ayrıntılarıyla çözülmüş olur. Aşağıdaki örnekte bir dosya açılmakta, ve sonrasında dosyaya yazma işlemleri için kullanan ifadeler çalıştırılmaktadır (Sunucu taraflı yazılmış koddur. İstemci tarafında dosyaya yazma işlemleri güvenlik açısından engellenmiştir. Eğer dosya, yazmak için açılırken bir exception fırlatılırsa, kod hata vermeden önce finally bloğu çalışır ve erişilecek dosyayı kapatır.

+ +
dosyaAç();
+try {
+  dosyayaYaz(veriler); // Bu kısım hata verebilir
+} catch(e) {
+  hatayıKaydetveGöster(e); // Hata ile ilgili bilgiler kaydedilir ve kullanıcıya bir hata mesajı sunulur.
+} finally {
+  dosyayıKapat(); // Dosyayı kapatır (hata olsa da olmasa da).
+}
+
+ +

Eğer finally bloğu bir değer geri döndürürse,  bu değer, try ve catch içerisindeki return ifadelerine bakmaksızın, try-catch-finally ifadesinin tamamı için geri dönüş değeri haline gelir:

+ +
function f() {
+  try {
+    console.log(0);
+    throw "hata";
+  } catch(e) {
+    console.log(1);
+    return true; // Buradaki return ifadesi,
+                 // finally bloğu tamamlanana dek duraklatılır.
+    console.log(2); // Üstteki return ifadesinden dolayı çalıştırılmaz.
+  } finally {
+    console.log(3);
+    return false; // catch kısmındaki return ifadesinin üstüne yazar ve geçersiz hale getirir.
+    console.log(4); // return'den dolayı çalıştırılmaz.
+  }
+  // Şimdi "return false" ifadesi çalıştırılır ve fonksiyondan çıkılır.
+  console.log(5); // Çalıştırılmaz.
+}
+f(); // Konsola 0 1 3 yazar ve false değerini döndürür.
+
+ +

finally bloğunun, geri dönüş değerlerinin üstüne yazma etkisi, aynı zamanda catch bloğu içerisindeki exception'lar için de aynı şekilde çalışır:

+ +
function f() {
+  try {
+    throw "hata";
+  } catch(e) {
+    console.log('İçerideki "hata" yakalandı.');
+    throw e; // Burası finally bloğu tamamlanana dek duraklatılır.
+  } finally {
+    return false; // Önceki "throw" ifadesinin üstüne yazar ve
+                  //  throw ifadesini geçersiz hale getirir.
+  }
+  // Şimdi "return false" ifadesi çalıştırılır.
+}
+
+try {
+  f();
+} catch(e) {
+  // f() fonksiyonundaki throw ifadesi geçersiz hale geldiği için
+  //  buradaki catch bloğu çalıştırılmaz.
+  console.log('Diğer "hata" yakalandı.');
+}
+
+// Ekran çıktısı: İçerideki "hata" yakalandı.
+ +

İçiçe try...catch ifadeleri

+ +

Bir veya daha fazla iç içe try...catch ifadeleri tanımlayabilirsiniz. Eğer içteki try...catch ifadesinin catch bloğu yoksa, bir dıştaki try...catch ifadesinin catch bloğu kontrol edilir.

+ +

Error nesnelerinin etkili kullanımı

+ +

Error nesnesinin türüne bağlı olarak,  'name' ve 'message' özellikleri vasıtasıyla daha anlamlı hata mesajları tanımlayabilirsiniz. 'name' özelliği, oluşan hatayı sınıflandırır (örn, 'DOMException' veya 'Error'). 'message' ise hata nesnesinin string'e dönüştürülmesine nazaran  genellikle daha kısa bir mesaj sunulmasına olanak tanır.

+ +

Eğer kendi exception nesnelerinizi fırlatıyorsanız ve bu özellikleri kullanarak hatayı anlamlı hale getirmek istiyorsanız Error sınıfının yapıcısının getirdiği avantajlardan faydalanabilirsiniz (örneğin catch bloğunuzun, kendi exception'larınız ile sistem exception'ları arasındaki farkı ayırt edemediği gibi durumlarda). Aşağıdaki örneği inceleyelim:

+ +
function hatayaMeyilliFonksiyon() {
+  if (hataVerenFonksiyonumuz()) {
+    throw (new Error('Hata oluştu'));
+  } else {
+    sistemHatasıVerenFonksiyon();
+  }
+}
+
+try {
+  hatayaMeyilliFonksiyon();
+}
+catch (e) {
+  console.log(e.name); // 'Error' yazar
+  console.log(e.message); // 'Hata oluştu' veya bir JavaScript hata mesajı yazar
+}
+ +

Promise nesneleri

+ +

ECMAScript2015 ile birlikte JavaScript'e, asenkron ve geciktirilmiş işlemlerin akış kontrolünün sağlanması için {{jsxref("Promise")}} nesneleri gelmiştir.

+ +

Bir Promise nesnesi aşağıdaki durumlardan birinde bulunur:

+ + + +

+ +

XHR ile resim yükleme

+ +

Promise ve XMLHttpRequest kullanarak bir resmin yüklenmesi için MDN GitHub promise-test sayfasında basit bir örnek mevcuttur. Ayrıca örneği canlı olarak da görebilirsiniz. Örnekteki her aşamaya yorum satırları eklenmiştir. Bu sayede Promise ve XHR mimarisini daha yakından izleyebilirsiniz. Aşağıda Promise nesnesinin akışını gösteren örneğin belgelendirilmemiş sürümü bulunmaktadır:

+ +
function resimYükle(url) {
+  return new Promise(function(başarıSonucundaFonk, hataSonucundaFonk) {
+    var istek = new XMLHttpRequest();
+    istek.open('GET', url);
+    istek.responseType = 'blob';
+    istek.onload = function() {
+      if (istek.status === 200) {
+        başarıSonucundaFonk(istek.cevabı);
+      } else {
+        hataSonucundaFonk(Error('Resim yüklenemedi; hata kodu:'
+                     + istek.hataKodu));
+      }
+    };
+    istek.onerror = function() {
+      hataSonucundaFonk(Error('Bir bağlantı hatası oluştu.'));
+    };
+    istek.send();
+  });
+}
+ +

Daha fazla detaylı bilgi için {{jsxref("Promise")}} sayfasına bakınız.

+ +
{{PreviousNext("Web/JavaScript/Guide/Grammar_and_types", "Web/JavaScript/Guide/Loops_and_iteration")}}
diff --git a/files/tr/web/javascript/guide/index.html b/files/tr/web/javascript/guide/index.html new file mode 100644 index 0000000000..5e4e177f58 --- /dev/null +++ b/files/tr/web/javascript/guide/index.html @@ -0,0 +1,122 @@ +--- +title: JavaScript Rehberi +slug: Web/JavaScript/Guide +tags: + - AJAX + - Intermediate + - JavaScript + - JavaScript_Guide + - NeedsTranslation + - TopicStub +translation_of: Web/JavaScript/Guide +--- +
{{jsSidebar("JavaScript Rehberi")}}
+ +

JavaSript Rehber'i size JavaScript'i nasıl kullanacağınızı ve dil hakkında genel bir bakış açısını sunar. JS hakkında daha geniş bir bilgiye ihtiyacınız varsa, JavaScript referansına bakınız.

+ + + + + + + + + +

{{Next("Web/JavaScript/Guide/Introduction")}}

diff --git a/files/tr/web/javascript/guide/introduction/index.html b/files/tr/web/javascript/guide/introduction/index.html new file mode 100644 index 0000000000..64b7180c80 --- /dev/null +++ b/files/tr/web/javascript/guide/introduction/index.html @@ -0,0 +1,134 @@ +--- +title: Introduction +slug: Web/JavaScript/Guide/Introduction +translation_of: Web/JavaScript/Guide/Introduction +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide", "Web/JavaScript/Guide/Grammar_and_types")}}
+ +

Bu bölümde JavaScript tanıtılacak ve bazı temel kavramları üzerine yoğunlaşılacaktır.

+ +

Halihazırda biliyor olmanız gerekenler

+ +

Bu rehber aşağıdakileri biliyor olduğunuzu varsayar:

+ + + +

JavaScript hakkında nereden bilgi edinirim

+ +

MDN'deki JavaScript dökümantasyonu şunları içerir:

+ + + +

JavaScript'te yeniyseniz, öğrenme alanı ve JavaScript Rehberi ile başlayınız. JavaScript temellerini sağlam olarak kavradığınızda, nesneler ve ifadeler ile ilgili detaylı bilgiler için özelleşmiş olan JavaScript Referansı'nı kullanabilirsiniz.

+ +

JavaScript nedir?

+ +

JavaScript, çok platformlu ve nesne yönelimli bir script dilidir. Küçük ve hafif bir dildir. Bir ana bilgisayar ortamında (örneğin, bir web tarayıcısında) JavaScript, programatik olarak kontrol sağlamak için kendi ortamındaki nesnelerine bağlanabilir.

+ +

Javascript, Array, Date, and Math gibi nesneleri içeren standart nesne kütüphanesini ve operatörler, kontrol yapıları ve ifadeler gibi temel dil setlerini içerir. JavaScript çekirdeği, ilave nesneler ile birlikte çeşitli amaçlar için genişletilebilir.Örneğin:

+ + + +

JavaScript ve Java

+ +

JavaScript ve Java bazı yönleriyle benzer olmakla birlikte temelde farklıdırlar.  JavaScript dili, Java'ya benzer fakat JavaScript'te, sabit Java tipleri ve Java'daki güçlü tip denetimi yoktur. JavaScript'in Java ile benzerlik göstermesi nedeniyle, isminin LiveScript'ten JavaScript'te değiştirilmesine neden olan Java'daki çoğu söz dizim ifadesini, isimlendirme düzenini ve basit kontrol akışını yapılarını destekler.

+ +

Java'nın tanımlanarak oluşturulmuş sınıfları derle-çalıştır sisteminin aksine; Javascript, veri tiplerinin ufak bir kısmı olan sayısal, boolean ve string veri tiplerini destekleyen çalışma sistemine sahiptir. JavaScript'te, diğer dillerde yaygın olarak kullanılan sınıf temelli nesne modeli yerine prototip temelli nesne modeli vardır. Prototip-temelli model, dinamik olarak miras almayı destekler. Böylelikle miras olarak alınan verinin, nesneler tarafından çoklanarak değiştirilebilmesini sağlanır. Ayrıca JavaScript, herhangi bir özel tanımlamaya gerek kalmadan fonksiyonları da destekler. Fonskiyonlar, esnek biçimlerde çalıştırılabilen metodlar halinde bir nesnenin özellikleri olabilirler.

+ +

JavaScript, Java'ya göre oldukça serbest biçimli bir dildir. Tüm değişkenleri, sınıfları ve metodları baştan tanımlamanıza gerek yoktur. Metodların public, private, veya protected olup olmadığı ile ilgili kaygılanmanıza gerek yoktur ve arayüzleri tanımlamanıza gerek yoktur. Değişkenler, parametreler ve fonksiyon dönüş türleri üstü kapalı türler değildir. (Tipine derleyici karar verir.)

+ +

Java, tip güvenliği ve hızlı çalıştırma için tanımlanmış bir sınıf-tabanlı programlama dilidir. Tip güvenliği, örneğin bir Java tamsayısını bir nesne referansına çeviremeyeceğiniz ya da gizli belleğe Java bytecodlarını bozarak ulaşamayacağınız anlamına gelir. Java'nın sınıf tabanlı modeli, programların sadece sınıflardan ve onların metodlarından oluştuğu anlamına gelir. Java'nın sınıf kalıtımı ve sıkı yazılışı, genellikle sıkıca bağlanmış nesne hiyerarşileri gerektirir. Bu gereksinimler, Java programlamayı JavaScript programlamadan daha kompleks yapar.

+ +

Javascript'in küçük yapısının aksine temelleri HyperTalk ve dBASE gibi dinamik tipli dillere dayanır.Bu betik dilleri; kolay söz dizimi, özelleştirilmiş tümleşik yapısı ve nesne oluşturma için minimum gereksinimlere ihtiyaç duyması sayesinde diğer dillere göre daha geniş programcı kitlesine hitap eder.

+ + + + + + + + + + + + + + + + + + + + + + + +
JavaScript ile Java dillerinin farkları
JavaScriptJava
Nesne temellidir. Nesnelerin türleri arasında bir ayrım söz konusu değildir. Prototype mekanizması ile oluşturulan kalıtım sayesinde, değişkenler ve metodlar herhangi bir objeye dinamik olarak eklenebilir.Nesne temellidir. Nesneler, sınıflar halinde birbirlerinden ayrılmışlardır ve örnekleri arasında oluşturulan kalıtım sınıf hiyerarşisi ile sağlanır. Sınıflar ve oluşturulan nesnelere dinamik olarak değişken ve metot eklemesi yapılamaz.
Değişkenlerin veri türlerinin tanımlanmasına gerek yoktur. İlk atama yapıldığında bir veri türüne sahip olurlar (dinamik tipleme). Örn: var degiskenAdi;Değişkenlerin veri türleri tanımlanmak zorundadır (statik tipleme). Örn: String degiskenAdi.
Otomatik olarak sabit diske yazılamazlar.Otomatik olarak sabit diske yazılabilirler.
+ +

Javascript ve Java ile ilgili farklılıklar hakkında daha fazla bilgi edinmek için, Details of the object model bölümüne göz atabilirsiniz.

+ +

JavaScript ve ECMAScript beyannamesi

+ +

JavaScript standardı, Ecma International tarafından belirlenir. Ecma International, JavaScript temelli standartlaştırılmış uluslararası bir programlama dili (ECMAScript) sunmak için, bilgi ve iletişim sistemlerinin standartlaştırılmasını sağlayan bir Avrupa derneğidir (ECMA'nın eski açınımı: European Computer Manufacturers Association (Avrupa Bilgisayar Üreticileri Derneği)). Standartlaştırılmış JavaScript versiyonu olan ECMAScript, standardı destekleyen tüm uygulamalarda aynı şekilde çalışır. Firmalar, açık standart dili kullanarak kendi Javascript dillerini oluşturabilirler. ECMAScript standardı ECMA-262 beyannamesi altında belgelendirilmiştir. JavaScript ve ECMAScript beyannameleri hakkında detaylı bilgi edinmek için New in JavaScript bölümüne bakabilirsiniz.

+ +

ECMA-262 standardı ayrıca ISO tarafından ISO-16262 olarak onaylanmıştır. Beyannameyi Ecma International'ın web sitesinde de bulabilirsiniz. ECMAScript beyannamesi, DOM (Doküman Nesnesi Modeli) hakkında bir tanımlama sunmaz. Zira DOM, World Wide Web Consortium (W3C) ve WHATWG (Web Hypertext Application Technology Working Group) tarafından standartlaştırılmıştır. DOM, HTML dokümanındaki nesnelerin, JavaScript betiğinize aktarılması için bir yol sunar. JavaScript ile programlamada kullanılan farklı teknolojiler hakkında bilgi edinmek için JavaScript technologies overview bölümüne bakabilirsiniz.

+ +

JavaScript dokümantasyonu ve ECMAScript beyannamesi farkları

+ +

ECMAScript beyannamesi, ECMAScript dilinin gerçekleştirilmesi için gereksinimleri belirler. Kendi ECMAScript gerçekleştiriminizi veya Firefox'taki SpiderMonkey gibi standartlara uyan bir ECMAScript motoru oluşturmanız için kullanışlıdır.

+ +

ECMAScript dokümanı, programcıların betik yazması için düzenlenmemiştir; betik yazmak hakkında bilgi edinmek için için JavaScript dokümantasyonunu kullanabilirsiniz.

+ +

ECMAScript beyannamesinin kullandığı terminoloji ve söz dizimine bir JavaScript programcısı alışkın olmayabilir. Dilin açıklaması ECMAScript'ten farklılık göstermesine rağmen, dilin kendisi aynı kalmıştır. Yani JavaScript, ECMAScript beyannamesinde belirlenen bütün fonksiyonelliği kapsar.

+ +

JavaScript dokümantasyonu, JavaScript programcısının aşina olduğu şekilde dilin özelliklerini ele alır.

+ +

JavaScript ile başlangıç

+ +

JavaScript'e başlamak kolaydır: tüm ihtiyacınız modern bir web tarayıcısı. Bu rehber, sadece Firefox'un son sürümlerinin desteklediği bazı JavaScript özelliklerini içerir, bu yüzden Firefox'un son sürümlerini kullanmak önerilir.

+ +

Firefox'ta çalıştırabileceğiniz iki tane kullanışlı JS aracı vardır: Web konsol ve Scratchpad.

+ +

Web Konsolu

+ +

Web Konsolu yüklü olan sayfanın yapısal içeriğini gösterir ve ayrıca o anda JavaScript kodlarınızı çalıştırabileceğiniz bir komut satırı da içerir.

+ +

Web konsolunu açmak için (Ctrl+Shift+K) komutunu kullanabilir veya "Geliştirici" menüsünden "Tarayıcı Konsolu"'nu seçebilirsiniz. Geliştirici menüsü Firefox'unuzda sağ üst bölümde bulunan "Araçlar" kısmındadır. Tarayıcı konsolu penceresi sayfanın üstüne açılır. Konsolun en alt kısmında aşağıdaki şekilde JavaScript kodunu gireceğiniz ve çıktısını alabileceğiniz bir komut satırı bulunmaktadır:

+ +

+ +

Karalama defteri

+ +

Web konsolu tek satırlı JavaScript kodunuzu çalıştırmak için iyi bir araçtır. Çok satırlı JavaScript kodları çalıştırmak istediginizde ise web konsolu'nun bunu yapma yetisi olsa da kullanışlı değildir ve yazdığınız kod örneklerini kaydedemez. Bu yüzden daha kompleks kod örnekleri için Karalama defteri daha iyi bir araçtır.

+ +

Karalama defterini açmak için (Shift+F4) komutunu kullanabilir veya "Web geliştirici" menüsünden "Karalama defteri"'ni seçebilirsiniz. JavaScript kodu yazıp çalıştırabileceğiniz, farklı bir editör penceresi açılır. Ayrıca komutlarınızı diskinizde saklayabilir ve diskinizden yükleyebilirsiniz.

+ +

+ +

Merhaba Dünya

+ +

JS'e başlamak için, Karalama defteri'ni açın ve ilk kodunuz olan "Merhaba Dünya"  yazın:

+ +
function selamVer(adiniz) {
+  alert("Merhaba" + adiniz);
+}
+
+selamVer("Dünya");
+
+ +

Yukarıda gösterildiği gibi yazdığınız kodu Karalama defteri penceresinden seçin ve çalıştırmak için Ctrl+R komutunu kullanın ve izleyin.

+ +

İlerleyen sayfalar, daha kompleks uygulamar yazabileceğiniz JS syntaxlarını ve dil özelliklerini içerir.

+ +

{{PreviousNext("Web/JavaScript/Guide", "Web/JavaScript/Guide/Grammar_and_types")}}

diff --git a/files/tr/web/javascript/guide/loops_and_iteration/index.html b/files/tr/web/javascript/guide/loops_and_iteration/index.html new file mode 100644 index 0000000000..8b224ab288 --- /dev/null +++ b/files/tr/web/javascript/guide/loops_and_iteration/index.html @@ -0,0 +1,331 @@ +--- +title: Döngüler ve yinelemeler +slug: Web/JavaScript/Guide/Loops_and_iteration +translation_of: Web/JavaScript/Guide/Loops_and_iteration +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Ifadeler", "Web/JavaScript/Guide/Functions")}}
+ +

Döngüler, bir işlemin art arda yapılması için hızlı ve kolay bir yöntem sunarlar. JavaScript Rehberi'nin bu bölümünde, JavaScript içerisinde yer alan çeşitli yineleme ifadeleri anlatılacaktır.

+ +

Döngüleri şu şekildeki basit bir bilgisayar oyunu olarak düşünebilirsiniz: Doğu yönünde 5 adım ilerle ve devamında batı yönünde 3 adım ilerleyerek hazineyi bul. Bu fikri basitçe kodlamak gerekirse:

+ +
var adım;
+for (adım = 0; adım < 5; adım++) {
+  // 5 defa ekrana yazıyor
+  // adım 0'dan 4'e kadar değerler alıyor.
+  console.log('Doğu yönünde bir adım atılıyor.');
+}
+
+ +

Birçok döngü türü vardır, fakat özünde hepsi aynı şeyi yaparlar: ardı ardına belirlenen bir işlemi gerçekleştirirler. Genelde gerçekleştirilen işlem adımı 0'dan başlar. Döngünün bitiş ve başlangıç noktalarının belirlenmesi için çeşitli döngü mekanizmaları mevcuttur. Bir döngünün diğer döngülere göre daha avantajlı olmasını sağlayan farklı durumlar vardır.

+ +

JavaScript'teki döngü ifadeleri aşağıdaki şekilde listelenmiştir:

+ + + +

for döngüsü

+ +

Bir {{jsxref("statements/for","for")}} döngüsü, belirlenen koşul sağlandığı sürece içerdiği komutların çalıştırılmasını sağlar. JavaScript'teki for döngüsü, Java ve C dilindeki for döngüsü ile benzerdir. For döngüsünün söz dizimi aşağıdaki şekildedir:

+ +
for ([başlangıçAtaması]; [koşulİfadesi]; [arttırımİfadesi])
+  ifade
+
+ +

Bir for döngüsündeki algoritmanın adımları aşağıdaki şekildedir:

+ +
    +
  1. Bir başlangıçAtaması ifadesi varsa çalıştırılır. Bu ifadede genellikle bir veya daha fazla döngü sayıcısına atama işlemi yapılır. Ayrıca değişken tanımı da yapılabilir.
  2. +
  3. koşulİfadesi çalıştırılır. Eğer koşulİfadesi değeri true ise, ifade çalıştırılabilir. Eğer koşulİfadesi değeri false ise, for döngüsünden çıkılır. Eğer koşulİfadesi boş geçilirse, değeri her zaman true olarak varsayılır ve sonsuz döngü oluşturulmuş olur.
  4. +
  5. ifade çalıştırılır. Birden fazla ifade çalıştırılacaksa, ifadeleri gruplamak için blok ifadesi ({ ... }) kullanılır.
  6. +
  7. arttırımİfadesi varsa çalıştırılır ve 2 numaralı adıma geri dönülür.
  8. +
+ +

Örnek

+ +

Aşağıdaki fonksiyon, scroll'lanabilen bir listedeki seçilen değerlerin sayısını sayan bir for ifadesi içerir (buradaki liste, çoklu seçimler yapabilmeye izin veren bir {{HTMLElement("select")}} elemanıdır) . for ifadesinde i değişkeni tanımlanır ve sıfır değeri atanır. i'nin değerinin, <select> elemanındaki {{HTMLElement("option")}} elemanlarının sayısından daha az olup olmadığı kontrol edilir, if ifadesini çalıştırılır, ve döngü her tamamlandığında i değişkeni bir arttırılır.

+ +
<form name="selectForm">
+  <p>
+    <label for="müzikTürleri">Sevdiğiniz müzik türlerini seçip aşağıdaki butona basınız:</label>
+    <select id="müzikTürleri" name="müzikTürleri" multiple="multiple">
+      <option selected="selected">Pop</option>
+      <option>Rap</option>
+      <option>Rock</option>
+      <option>Arabesk</option>
+      <option>Türk Sanat Müziği</option>
+      <option>Klasik Müzik</option>
+    </select>
+  </p>
+  <p><input id="btn" type="button" value="Kaç tanesi seçildi?" /></p>
+</form>
+
+<script>
+function kaçTane(müzikTürleri) {
+  var seçilenMüzikSayısı = 0;
+  for (var i = 0; i < müzikTürleri.options.length; i++) {
+    if (müzikTürleri.options[i].selected) {
+      seçilenMüzikSayısı++;
+    }
+  }
+  return seçilenMüzikSayısı;
+}
+
+var btn = document.getElementById("btn");
+btn.addEventListener("click", function(){
+  alert('Seçilen müzik türü sayısı: ' + kaçTane(document.selectForm.müzikTürleri))
+});
+</script>
+
+
+ +

do...while döngüsü

+ +

{{jsxref("statements/do...while", "do...while")}} döngüsü, belirlenen bir koşul sağlandığı sürece döngünün çalıştırılmasına olanak tanır. Bir do...while döngüsü aşağıdaki gibidir:

+ +
do
+  ifade
+while (koşul);
+
+ +

koşul kontrol edilmeden hemen önce ifade çalıştırılır. Çoklu ifadelerin çalıştırılması için, blok ifadesi ({...}) kullanılarak ifadeler gruplandırılır. Eğer koşul sağlanırsa, ifade tekrar çalıştırılır. Çalıştırıldıktan sonra, koşul tekrar kontrol edilir. Eğer koşul sağlanmazsa, ifadenin çalıştırılması durdurulur ve do...while döngüsünden sonraki komutlar çalıştırılır. koşul kontrol edilmeden hemen önce ifade çalıştırıldığı için, koşul değeri false olsa bile blok satırınız içerisindeki kodlar 1 defa çalıştırılır.

+ +

Örnek 1

+ +

Aşağıdaki örnekte, do döngüsü en az bir kere çalıştırılır, ve i değişkeninin değeri 5'ten küçük olduğu sürece çalıştırma devam eder:

+ +
var i = 0;
+do {
+  i += 1;
+  console.log(i);
+} while (i < 5);
+
+ +

while döngüsü

+ +

Bir {{jsxref("statements/while","while")}} döngüsü, belirlenen koşul sağlandığı sürece çalıştırılmaya devam eder. Örnek bir while döngüsü aşağıdaki gibidir:

+ +
while (koşul)
+  ifade
+
+ +

Döngü içerisindeki ifade çalıştırılmadan önce koşul kontrol edilir. Eğer koşul sağlanırsa, ifade çalıştırılır ve koşul tekrar kontrol edilir. Eğer koşul sağlanmazsa, döngü içerisindeki ifadenin çalıştırılması durdurulur ve while döngüsünden çıkılarak sonraki komutlar çalıştırılır.

+ +

Çoklu ifadelerin çalıştırılması için, blok ifadesi ({...}) kullanılarak ifadeler gruplanır.

+ +

Örnek 1

+ +

Aşağıdaki while döngüsü, n değişkeni 3'ten küçük olduğu sürece çalıştırılır:

+ +
var n = 0;
+var x = 0;
+while (n < 3) {
+  n++;
+  x += n;
+}
+
+ +

Her döngüde, n değişkeninin değeri 1 arttırılır ve x'e eklenir. Bunun sonucunda x ve n değişkenleri aşağıdaki değerleri alırlar:

+ + + +

3. kez döngü çalıştırılıp tamamlandığında, n < 3 koşulu artık true değerini almaz ve döngüden çıkılır.

+ +

Örnek 2

+ +

Sonsuz döngülerden uzak durulmalıdır. Döngü içerisindeki koşulun, eninde sonunda false değerini alacağı emin olunmalıdır; aksi taktirde, döngü sonsuza dek çalışır. Aşağıdaki while döngüsündeki ifade sonsuza dek çalışır, çünkü koşul asla false değerini alamaz:

+ +
while (true) {
+  console.log("Merhaba dünya");
+}
+ +

Etiketlenmiş ifadeler

+ +

Bir {{jsxref("statements/label","etiketlenmiş ifadede")}} , bir anahtar kelime ve bu kelimeye bağlı çalıştırılacak bir ifade bulunur.Anahtar kelime kullanılarak, program içerisindeki herhangi bir yerde, anahtar kelime ile ilişkili ifade çalıştırılabilir. Örneğin, bir döngü, anahtar kelime ile etiketlenerek, uygulama içerisindeki herhangi bir yerden çalıştırılabilir.

+ +

Etiketlenmiş bir ifade aşağıdaki şekildedir:

+ +
etiket :
+   çalıştırılacak_ifade
+
+ +

Etiket adı, herhangi bir değişken adının aldığı şekilde değerler alabilir. Etiket ile tanımlanan çalıştırılacak_ifade içerisinde herhangi bir komut yer alabilir.

+ +

Örnek

+ +

Bu örnekte, döngüyüİşaretle etiketi while döngüsünü tanımlar.

+ +
döngüyüİşaretle:
+while (işaret == true) {
+   merhabaDünya();
+}
+ +

break ifadesi

+ +

{{jsxref("statements/break","break")}} ifadesi kullanılarak bir döngüden, switch ifadesinden veya herhangi bir etiketlenmiş ifadeden çıkılabilir.

+ + + +

break ifadesinin söz dizimi aşağıdaki gibidir:

+ +
break [etiket];
+
+ +

Bu söz diziminin ilk ifadesi (break) ile, break'i çevreleyen en içteki döngü veya switch'ten çıkılır; ikinci ifade ([etiket]) ile belirlenen etiketten çıkılması sağlanır.

+ +

Örnek 1

+ +

Aşağıdaki örnekte, değer'e eşit olan dizi elemanı bulununcaya dek dizi içerisindeki elemanlar bir döngüde gezilir.

+ +
for (var i = 0; i < a.length; i++) {
+  if (a[i] == değer) {
+    break;
+  }
+}
+ +

Örnek 2: Bir etiketten çıkma

+ +
var x = 0;
+var z = 0;
+
+döngüdenÇıkmaEtiketi: while (true) {
+  console.log("Dıştaki döngüler: " + x);
+  x += 1;
+  z = 1;
+  while (true) {
+    console.log("İçteki döngüler: " + z);
+    z += 1;
+    if (z === 10 && x === 10) {
+      break döngüdenÇıkmaEtiketi;
+    } else if (z === 10) {
+      break;
+    }
+  }
+}
+
+ +

continue ifadesi

+ +

{{jsxref("statements/continue","continue")}} ifadesi; while, do-while, for, veya etiketlenmiş ifadelere tekrar girilmesini sağlar.

+ + + +

continue ifadesinin söz dizimi aşağıdaki gibidir:

+ +
continue [etiket];
+
+ +

Örnek 1

+ +

Aşağıdaki örnekte yer alan while döngüsündeki continue ifadesi, i'nin değeri yalnızca 3 olduğunda çalıştırılmaktadır. Böylece n, sırasıyla şu değerleri alır: 1, 3, 7, 12.

+ +
var i = 0;
+var n = 0;
+while (i < 5) {
+  i++;
+  if (i == 3) {
+    continue;
+  }
+  n += i;
+}
+
+ +

Örnek 2

+ +

Aşağıdaki örnekte bulunan kontrolivej etiketinde yer alan ifadede, kontrolj etiketli diğer bir ifade yer almaktadır. Eğer continue ifadesi ile karşılaşılırsa, uygulama kontrolj'nin o anki döngüsünü sonlandırır ve sonraki iterasyona geçer. Her continue ifadesi ile karşılaşıldığında, kontrolj döngüsü false değerini döndürene dek  devam eder. false döndürdüğünde, döngüden çıkılır ve döngüden sonra gelen kontrolivej ifadesinin kalan kısmı tamamlanır. kontrolivej döngüsüne tekrar girilir. i değişkeni 4'ten büyük oluncaya dek kontrolivej etiketinin çalıştırılmasına devam ettirilir.

+ +

Eğer continue ifadesi, kontrolj etiketi yerine kontrolivej etiketini içerseydi, program kontrolivej ifadesinin altındaki while döngüsünden devam edecekti.

+ +
kontrolivej:
+  while (i < 4) {
+    console.log(i);
+    i += 1;
+    kontrolj:
+      while (j > 4) {
+        console.log(j);
+        j -= 1;
+        if ((j % 2) == 0) {
+          continue kontrolj;
+        }
+        console.log(j + " tek sayıdır.");
+      }
+      console.log("i = " + i);
+      console.log("j = " + j);
+  }
+ +

for...in ifadesi

+ +

{{jsxref("statements/for...in","for...in")}} döngüsü, bir nesnenin sayılabilir (enumerable) özelliklerinin üzerinde dolaşılmasını sağlar. Her bir özellik için JavaScript, belirlenen ifadeleri çalıştırır. Bir for...in döngüsü aşağıdaki şekilde oluşturulur:

+ +
for (değişken in nesne) {
+  çalıştırılacak_ifadeler
+}
+
+ +

Örnek

+ +

Aşağıdaki fonksiyon, bir nesne ve nesnenin adını parametre olarak alır. Sonrasında nesnenin tüm özellikleri üzerinde gezer ve nesnede bulunan özelliklerin adını ve değerini listeleyen bir string döndürür. 

+ +
function özellikleriListeOlarakVer(nesne, nesnenin_adi) {
+  var sonuç = "";
+  for (var i in nesne) {
+    sonuç += nesnenin_adi + "." + i + " = " + nesne[i] + "<br>";
+  }
+  sonuç += "<hr>";
+  return sonuç;
+}
+
+ +

marka ve model özelliklerini içeren bir araba nesnesi için sonuç, aşağıdaki şekilde olacaktır:

+ +
araba.marka = Tesla
+araba.model = Model S
+
+ +

Dizilerde kullanımı

+ +

{{jsxref("Array")}} elemanlarında dolaşmak için for...in kullanımı çok cazip gözükse de for...in ifadesi, sayısal indekslere ek olarak kullanıcı tanımlı özelliklerin de isimlerini döndürür. Bu yüzden dizi üzerinde gezmek için, sayısal indeksler ile birlikte kullanılan geleneksel {{jsxref("statements/for","for")}} döngüsü daha elverişlidir. Çünkü örneğin bir Array nesnesinine özel bir değişken veya fonksiyon eklerseniz, for...in ifadesi dizi elemanlarının yanısıra eklediğiniz kullanıcı tanımlı özellikleri de getirir

+ +

for...of ifadesi

+ +

{{jsxref("statements/for...of","for...of")}} ifadesi bir döngü oluşturur ve gezilebilir (iterable) nesneler ({{jsxref("Array")}}, {{jsxref("Map")}}, {{jsxref("Set")}}, {{jsxref("functions/arguments","arguments")}} nesnesi vb.) üzerinde gezer.

+ +
for (değişken of nesne) {
+  çalıştırılacak_ifadeler
+}
+ +

Aşağıdaki örnekte, for...of döngüsü ve {{jsxref("statements/for...in","for...in")}} döngüsü arasındaki fark gösterilmektedir. for...in döngüsü nesne değişkenlerinin isimleri üzerinde gezerken, for...of döngüsü ise değişkenlerin değerleri üzerinde gezer:

+ +
let dizi = [3, 5, 7];
+dizi.selam = "merhaba";
+
+for (let i in dizi) {
+   console.log(i); // Çıktısı: "0", "1", "2", "selam"
+   console.log(typeof i); //string tipi
+}
+
+for (let i of dizi) {
+   console.log(i); // Çıktısı: 3, 5, 7
+   console.log(typeof i); //degiskenin sahip old. tip
+}
+
+ +

{{PreviousNext("Web/JavaScript/Guide/Ifadeler", "Web/JavaScript/Guide/Functions")}}

diff --git "a/files/tr/web/javascript/guide/nesneler_ile_\303\247al\304\261\305\237mak/index.html" "b/files/tr/web/javascript/guide/nesneler_ile_\303\247al\304\261\305\237mak/index.html" new file mode 100644 index 0000000000..0782b4db6c --- /dev/null +++ "b/files/tr/web/javascript/guide/nesneler_ile_\303\247al\304\261\305\237mak/index.html" @@ -0,0 +1,504 @@ +--- +title: Nesnelerle çalışmak +slug: Web/JavaScript/Guide/Nesneler_ile_çalışmak +translation_of: Web/JavaScript/Guide/Working_with_Objects +--- +
{{jsSidebar("JavaScript Rehberi")}} {{PreviousNext("Web/JavaScript/Guide/Keyed_collections", "Web/JavaScript/Guide/Details_of_the_Object_Model")}}
+ +

JavaScript basit bir nesne tabanlı paradigmada tasarlanmıştır. Bir nesne bir özellikler koleksiyonudur ve bir özellik bir ad (veya anahtar) ile bir değer arasındaki ilişkidir. Bir özelliğin değeri bir fonksiyon olabilir, bu durumda özellik bir metod olarak bilinir. Tarayıcıda önceden tanımlanmış olan nesnelere ek olarak, kendi nesnelerinizi de tanımlayabilirsiniz. Bu bölümde, nesnelerin, özelliklerin, fonksiyonların ve metodların nasıl kullanıldığı ve kendi nesnelerinizin nasıl oluşturulacağı açıklanmaktadır.

+ +

Nesnelere genel bakış

+ +

JavaScript'teki nesneler, diğer birçok programlama dilinde olduğu gibi, gerçek hayattaki nesnelerle karşılaştırılabilir. JavaScript'teki nesneler kavramı gerçek hayattaki somut nesnelerle anlaşılabilir.

+ +

JavaScript'te bir nesne, özellikleri ve tipiyle bağımsız bir varlıktır. Örneğin bir fincanla karşılaştırın. Bir fincan, özellikleri olan bir nesnedir. Bir fincan bir renge, bir tasarıma, ağırlığa, yapıldığı bir malzemeye vs. sahiptir. Aynı şekilde, JavaScript nesnelerinin de özelliklerini tanımlayan özellikleri olabilir.

+ +

Nesneler ve özellikleri

+ +

A JavaScript object has properties associated with it. A property of an object can be explained as a variable that is attached to the object. Object properties are basically the same as ordinary JavaScript variables, except for the attachment to objects. The properties of an object define the characteristics of the object. You access the properties of an object with a simple dot-notation:

+ +
objectName.propertyName
+
+ +

Like all JavaScript variables, both the object name (which could be a normal variable) and property name are case sensitive. You can define a property by assigning it a value. For example, let's create an object named myCar and give it properties named make, model, and year as follows:

+ +
var myCar = new Object();
+myCar.make = 'Ford';
+myCar.model = 'Mustang';
+myCar.year = 1969;
+
+ +

Unassigned properties of an object are {{jsxref("undefined")}} (and not {{jsxref("null")}}).

+ +
myCar.color; // undefined
+ +

Properties of JavaScript objects can also be accessed or set using a bracket notation (for more details see property accessors). Objects are sometimes called associative arrays, since each property is associated with a string value that can be used to access it. So, for example, you could access the properties of the myCar object as follows:

+ +
myCar['make'] = 'Ford';
+myCar['model'] = 'Mustang';
+myCar['year'] = 1969;
+
+ +

An object property name can be any valid JavaScript string, or anything that can be converted to a string, including the empty string. However, any property name that is not a valid JavaScript identifier (for example, a property name that has a space or a hyphen, or that starts with a number) can only be accessed using the square bracket notation. This notation is also very useful when property names are to be dynamically determined (when the property name is not determined until runtime). Examples are as follows:

+ +
// four variables are created and assigned in a single go,
+// separated by commas
+var myObj = new Object(),
+    str = 'myString',
+    rand = Math.random(),
+    obj = new Object();
+
+myObj.type              = 'Dot syntax';
+myObj['date created']   = 'String with space';
+myObj[str]              = 'String value';
+myObj[rand]             = 'Random Number';
+myObj[obj]              = 'Object';
+myObj['']               = 'Even an empty string';
+
+console.log(myObj);
+
+ +

Please note that all keys in the square bracket notation are converted to string unless they're Symbols, since JavaScript object property names (keys) can only be strings or Symbols (at some point, private names will also be added as the class fields proposal progresses, but you won't use them with [] form). For example, in the above code, when the key obj is added to the myObj, JavaScript will call the {{jsxref("Object.toString", "obj.toString()")}} method, and use this result string as the new key.

+ +

You can also access properties by using a string value that is stored in a variable:

+ +
var propertyName = 'make';
+myCar[propertyName] = 'Ford';
+
+propertyName = 'model';
+myCar[propertyName] = 'Mustang';
+
+ +

You can use the bracket notation with for...in to iterate over all the enumerable properties of an object. To illustrate how this works, the following function displays the properties of the object when you pass the object and the object's name as arguments to the function:

+ +
function showProps(obj, objName) {
+  var result = ``;
+  for (var i in obj) {
+    // obj.hasOwnProperty() is used to filter out properties from the object's prototype chain
+    if (obj.hasOwnProperty(i)) {
+      result += `${objName}.${i} = ${obj[i]}\n`;
+    }
+  }
+  return result;
+}
+
+ +

So, the function call showProps(myCar, "myCar") would return the following:

+ +
myCar.make = Ford
+myCar.model = Mustang
+myCar.year = 1969
+ +

Enumerate the properties of an object

+ +

Starting with ECMAScript 5, there are three native ways to list/traverse object properties:

+ + + +

Before ECMAScript 5, there was no native way to list all properties of an object. However, this can be achieved with the following function:

+ +
function listAllProperties(o) {
+	var objectToInspect;
+	var result = [];
+
+	for(objectToInspect = o; objectToInspect !== null;
+           objectToInspect = Object.getPrototypeOf(objectToInspect)) {
+        result = result.concat(
+            Object.getOwnPropertyNames(objectToInspect)
+        );
+    }
+
+	return result;
+}
+
+ +

This can be useful to reveal "hidden" properties (properties in the prototype chain which are not accessible through the object, because another property has the same name earlier in the prototype chain). Listing accessible properties only can easily be done by removing duplicates in the array.

+ +

Creating new objects

+ +

JavaScript has a number of predefined objects. In addition, you can create your own objects. You can create an object using an object initializer. Alternatively, you can first create a constructor function and then instantiate an object invoking that function in conjunction with the new operator.

+ +

Using object initializers

+ +

In addition to creating objects using a constructor function, you can create objects using an object initializer. Using object initializers is sometimes referred to as creating objects with literal notation. "Object initializer" is consistent with the terminology used by C++.

+ +

The syntax for an object using an object initializer is:

+ +
var obj = { property_1:   value_1,   // property_# may be an identifier...
+            2:            value_2,   // or a number...
+            // ...,
+            'property n': value_n }; // or a string
+
+ +

where obj is the name of the new object, each property_i is an identifier (either a name, a number, or a string literal), and each value_i is an expression whose value is assigned to the property_i. The obj and assignment is optional; if you do not need to refer to this object elsewhere, you do not need to assign it to a variable. (Note that you may need to wrap the object literal in parentheses if the object appears where a statement is expected, so as not to have the literal be confused with a block statement.)

+ +

Object initializers are expressions, and each object initializer results in a new object being created whenever the statement in which it appears is executed. Identical object initializers create distinct objects that will not compare to each other as equal. Objects are created as if a call to new Object() were made; that is, objects made from object literal expressions are instances of Object.

+ +

The following statement creates an object and assigns it to the variable x if and only if the expression cond is true:

+ +
if (cond) var x = {greeting: 'hi there'};
+
+ +

The following example creates myHonda with three properties. Note that the engine property is also an object with its own properties.

+ +
var myHonda = {color: 'red', wheels: 4, engine: {cylinders: 4, size: 2.2}};
+
+ +

You can also use object initializers to create arrays. See array literals.

+ +

Using a constructor function

+ +

Alternatively, you can create an object with these two steps:

+ +
    +
  1. Define the object type by writing a constructor function. There is a strong convention, with good reason, to use a capital initial letter.
  2. +
  3. Create an instance of the object with new.
  4. +
+ +

To define an object type, create a function for the object type that specifies its name, properties, and methods. For example, suppose you want to create an object type for cars. You want this type of object to be called Car, and you want it to have properties for make, model, and year. To do this, you would write the following function:

+ +
function Car(make, model, year) {
+  this.make = make;
+  this.model = model;
+  this.year = year;
+}
+
+ +

Notice the use of this to assign values to the object's properties based on the values passed to the function.

+ +

Now you can create an object called mycar as follows:

+ +
var mycar = new Car('Eagle', 'Talon TSi', 1993);
+
+ +

This statement creates mycar and assigns it the specified values for its properties. Then the value of mycar.make is the string "Eagle", mycar.year is the integer 1993, and so on.

+ +

You can create any number of Car objects by calls to new. For example,

+ +
var kenscar = new Car('Nissan', '300ZX', 1992);
+var vpgscar = new Car('Mazda', 'Miata', 1990);
+
+ +

An object can have a property that is itself another object. For example, suppose you define an object called person as follows:

+ +
function Person(name, age, sex) {
+  this.name = name;
+  this.age = age;
+  this.sex = sex;
+}
+
+ +

and then instantiate two new person objects as follows:

+ +
var rand = new Person('Rand McKinnon', 33, 'M');
+var ken = new Person('Ken Jones', 39, 'M');
+
+ +

Then, you can rewrite the definition of Car to include an owner property that takes a person object, as follows:

+ +
function Car(make, model, year, owner) {
+  this.make = make;
+  this.model = model;
+  this.year = year;
+  this.owner = owner;
+}
+
+ +

To instantiate the new objects, you then use the following:

+ +
var car1 = new Car('Eagle', 'Talon TSi', 1993, rand);
+var car2 = new Car('Nissan', '300ZX', 1992, ken);
+
+ +

Notice that instead of passing a literal string or integer value when creating the new objects, the above statements pass the objects rand and ken as the arguments for the owners. Then if you want to find out the name of the owner of car2, you can access the following property:

+ +
car2.owner.name
+
+ +

Note that you can always add a property to a previously defined object. For example, the statement

+ +
car1.color = 'black';
+
+ +

adds a property color to car1, and assigns it a value of "black." However, this does not affect any other objects. To add the new property to all objects of the same type, you have to add the property to the definition of the Car object type.

+ +

Using the Object.create method

+ +

Objects can also be created using the {{jsxref("Object.create()")}} method. This method can be very useful, because it allows you to choose the prototype object for the object you want to create, without having to define a constructor function.

+ +
// Animal properties and method encapsulation
+var Animal = {
+  type: 'Invertebrates', // Default value of properties
+  displayType: function() {  // Method which will display type of Animal
+    console.log(this.type);
+  }
+};
+
+// Create new animal type called animal1
+var animal1 = Object.create(Animal);
+animal1.displayType(); // Output:Invertebrates
+
+// Create new animal type called Fishes
+var fish = Object.create(Animal);
+fish.type = 'Fishes';
+fish.displayType(); // Output:Fishes
+ +

Inheritance

+ +

All objects in JavaScript inherit from at least one other object. The object being inherited from is known as the prototype, and the inherited properties can be found in the prototype object of the constructor. See Inheritance and the prototype chain for more information.

+ +

Indexing object properties

+ +

You can refer to a property of an object either by its property name or by its ordinal index. If you initially define a property by its name, you must always refer to it by its name, and if you initially define a property by an index, you must always refer to it by its index.

+ +

This restriction applies when you create an object and its properties with a constructor function (as we did previously with the Car object type) and when you define individual properties explicitly (for example, myCar.color = "red"). If you initially define an object property with an index, such as myCar[5] = "25 mpg", you subsequently refer to the property only as myCar[5].

+ +

The exception to this rule is array-like object reflected from HTML, such as the forms array-like object. You can always refer to objects in these array-like objects by either their ordinal number (based on where they appear in the document) or their name (if defined). For example, if the second <FORM> tag in a document has a NAME attribute of "myForm", you can refer to the form as document.forms[1] or document.forms["myForm"] or document.forms.myForm.

+ +

Defining properties for an object type

+ +

You can add a property to a previously defined object type by using the prototype property. This defines a property that is shared by all objects of the specified type, rather than by just one instance of the object. The following code adds a color property to all objects of type Car, and then assigns a value to the color property of the object car1.

+ +
Car.prototype.color = null;
+car1.color = 'black';
+
+ +

See the prototype property of the Function object in the JavaScript reference for more information.

+ +

Defining methods

+ +

A method is a function associated with an object, or, simply put, a method is a property of an object that is a function. Methods are defined the way normal functions are defined, except that they have to be assigned as the property of an object. See also method definitions for more details. An example is:

+ +
objectName.methodname = functionName;
+
+var myObj = {
+  myMethod: function(params) {
+    // ...do something
+  }
+
+  // OR THIS WORKS TOO
+
+  myOtherMethod(params) {
+    // ...do something else
+  }
+};
+
+ +

where objectName is an existing object, methodname is the name you are assigning to the method, and functionName is the name of the function.

+ +

You can then call the method in the context of the object as follows:

+ +
object.methodname(params);
+
+ +

You can define methods for an object type by including a method definition in the object constructor function. You could define a function that would format and display the properties of the previously-defined Car objects; for example,

+ +
function displayCar() {
+  var result = `A Beautiful ${this.year} ${this.make} ${this.model}`;
+  pretty_print(result);
+}
+
+ +

where pretty_print is a function to display a horizontal rule and a string. Notice the use of this to refer to the object to which the method belongs.

+ +

You can make this function a method of Car by adding the statement

+ +
this.displayCar = displayCar;
+
+ +

to the object definition. So, the full definition of Car would now look like

+ +
function Car(make, model, year, owner) {
+  this.make = make;
+  this.model = model;
+  this.year = year;
+  this.owner = owner;
+  this.displayCar = displayCar;
+}
+
+ +

Then you can call the displayCar method for each of the objects as follows:

+ +
car1.displayCar();
+car2.displayCar();
+
+ +

Using this for object references

+ +

JavaScript has a special keyword, this, that you can use within a method to refer to the current object. For example, suppose you have 2 objects, Managerand Intern. Each object have their own nameage and job.  In the function sayHi(), notice there is this.name. When added to the 2 objects they can be called and returns the 'Hello, My name is' then adds the name value from that specific object. As shown below. 

+ +
const Manager = {
+  name: "John",
+  age: 27,
+  job: "Software Engineer"
+}
+const Intern= {
+  name: "Ben",
+  age: 21,
+  job: "Software Engineer Intern"
+}
+
+function sayHi() {
+    console.log('Hello, my name is', this.name)
+}
+
+// add sayHi function to both objects
+Manager.sayHi = sayHi;
+Intern.sayHi = sayHi;
+
+Manager.sayHi() // Hello, my name is John'
+Intern.sayHi() // Hello, my name is Ben'
+
+ +

The this refers to the object that it is in. You can create a new function called howOldAmI()which logs a sentence saying how old the person is. 

+ +
function howOldAmI (){
+  console.log('I am ' + this.age + ' years old.')
+}
+Manager.howOldAmI = howOldAmI;
+Manager.howOldAmI() // I am 27 years old.
+
+ +

Defining getters and setters

+ +

A getter is a method that gets the value of a specific property. A setter is a method that sets the value of a specific property. You can define getters and setters on any predefined core object or user-defined object that supports the addition of new properties. The syntax for defining getters and setters uses the object literal syntax.

+ +

The following illustrates how getters and setters could work for a user-defined object o.

+ +
var o = {
+  a: 7,
+  get b() {
+    return this.a + 1;
+  },
+  set c(x) {
+    this.a = x / 2;
+  }
+};
+
+console.log(o.a); // 7
+console.log(o.b); // 8
+o.c = 50;
+console.log(o.a); // 25
+
+ +

The o object's properties are:

+ + + +

Please note that function names of getters and setters defined in an object literal using "[gs]et property()" (as opposed to __define[GS]etter__ ) are not the names of the getters themselves, even though the [gs]et propertyName(){ } syntax may mislead you to think otherwise. To name a function in a getter or setter using the "[gs]et property()" syntax, define an explicitly named function programmatically using {{jsxref("Object.defineProperty")}} (or the {{jsxref("Object.defineGetter", "Object.prototype.__defineGetter__")}} legacy fallback).

+ +

The following code illustrates how getters and setters can extend the {{jsxref("Date")}} prototype to add a year property to all instances of the predefined Date class. It uses the Date class's existing getFullYear and setFullYear methods to support the year property's getter and setter.

+ +

These statements define a getter and setter for the year property:

+ +
var d = Date.prototype;
+Object.defineProperty(d, 'year', {
+  get: function() { return this.getFullYear(); },
+  set: function(y) { this.setFullYear(y); }
+});
+
+ +

These statements use the getter and setter in a Date object:

+ +
var now = new Date();
+console.log(now.year); // 2000
+now.year = 2001; // 987617605170
+console.log(now);
+// Wed Apr 18 11:13:25 GMT-0700 (Pacific Daylight Time) 2001
+
+ +

In principle, getters and setters can be either

+ + + +

When defining getters and setters using object initializers all you need to do is to prefix a getter method with get and a setter method with set. Of course, the getter method must not expect a parameter, while the setter method expects exactly one parameter (the new value to set). For instance:

+ +
var o = {
+  a: 7,
+  get b() { return this.a + 1; },
+  set c(x) { this.a = x / 2; }
+};
+
+ +

Getters and setters can also be added to an object at any time after creation using the Object.defineProperties method. This method's first parameter is the object on which you want to define the getter or setter. The second parameter is an object whose property names are the getter or setter names, and whose property values are objects for defining the getter or setter functions. Here's an example that defines the same getter and setter used in the previous example:

+ +
var o = { a: 0 };
+
+Object.defineProperties(o, {
+    'b': { get: function() { return this.a + 1; } },
+    'c': { set: function(x) { this.a = x / 2; } }
+});
+
+o.c = 10; // Runs the setter, which assigns 10 / 2 (5) to the 'a' property
+console.log(o.b); // Runs the getter, which yields a + 1 or 6
+
+ +

Which of the two forms to choose depends on your programming style and task at hand. If you already go for the object initializer when defining a prototype you will probably most of the time choose the first form. This form is more compact and natural. However, if you need to add getters and setters later — because you did not write the prototype or particular object — then the second form is the only possible form. The second form probably best represents the dynamic nature of JavaScript — but it can make the code hard to read and understand.

+ +

Deleting properties

+ +

You can remove a non-inherited property by using the delete operator. The following code shows how to remove a property.

+ +
// Creates a new object, myobj, with two properties, a and b.
+var myobj = new Object;
+myobj.a = 5;
+myobj.b = 12;
+
+// Removes the a property, leaving myobj with only the b property.
+delete myobj.a;
+console.log ('a' in myobj); // output: "false"
+
+ +

You can also use delete to delete a global variable if the var keyword was not used to declare the variable:

+ +
g = 17;
+delete g;
+
+ +

Comparing objects

+ +

In JavaScript, objects are a reference type. Two distinct objects are never equal, even if they have the same properties. Only comparing the same object reference with itself yields true.

+ +
// Two variables, two distinct objects with the same properties
+var fruit = {name: 'apple'};
+var fruitbear = {name: 'apple'};
+
+fruit == fruitbear; // return false
+fruit === fruitbear; // return false
+ +
// Two variables, a single object
+var fruit = {name: 'apple'};
+var fruitbear = fruit;  // Assign fruit object reference to fruitbear
+
+// Here fruit and fruitbear are pointing to same object
+fruit == fruitbear; // return true
+fruit === fruitbear; // return true
+
+fruit.name = 'grape';
+console.log(fruitbear); // output: { name: "grape" }, instead of { name: "apple" }
+
+ +

For more information about comparison operators, see Comparison operators.

+ +

See also

+ + + +

{{PreviousNext("Web/JavaScript/Guide/Regular_Expressions", "Web/JavaScript/Guide/Details_of_the_Object_Model")}}

-- cgit v1.2.3-54-g00ecf