
این دستگاه هر گونه کامپیوتر، دوربین و غیره را که به شبکه بی سیم تحت حفاظت وصل شده باشد شناسایی کرده و بعد از علام هشدار به صاحب شبکه، به صورت خودکار از شبکه قطع می کند.
قیمت دستگاه بین 50 تا 100 دلار است.

این دستگاه هر گونه کامپیوتر، دوربین و غیره را که به شبکه بی سیم تحت حفاظت وصل شده باشد شناسایی کرده و بعد از علام هشدار به صاحب شبکه، به صورت خودکار از شبکه قطع می کند.
قیمت دستگاه بین 50 تا 100 دلار است.
We will cover here some of the key concepts of JavaScript to get us started. If you have not checked JavaScript for the past few years or if you are new to JavaScript, I hope you find this useful.
We will start by covering the language basics like variables, functions, scope, and the different types, but we will not spend much time on the absolute basics like operators, or what is a function or a variable, you probably already know all that as a developer. We will discover JavaScript by going through simple examples and for each of these, highlight specific behaviors and approach the language from an interactive developer standpoint, coming from other technologies like Flash (ActionScript 3), Java, C# or simply native (C++).
Like other managed languages, JavaScript runs inside a JavaScript VM (Virtual Machine), one key difference to note is that unlike executing bytecode, JavaScript VMs are source based, translating JavaScript source code directly to native code by using what is called a JIT (Just in Time compiler) when available. The JIT performs optimization at runtime (just in time) to leverage platform specific optimizations depending on the architecture the code is being run on. Of course, most browsers available today run JavaScript, the list below highlights the most popular JavaScript VMs today in the industry:
JavaScript can provide some serious advantages over low-level languages like automatic memory allocation and collection through garbage collectors. This, however comes at the cost of speed. But managed languages provides so much value in terms of productivity and platform reach that developers today tend to favor them over low-level languages, despite the loss of performance because of the higher cost for those languages when it comes to targeting multiple platforms.
Before we get started, it is important to differentiate how browsers work. On one side we have the core language, JavaScript, and on the other side we have the browser APIs. Historically, JavaScript and the DOM used to be tightly coupled and most tutorials would cover both at the same time, but they evolved into strong separate entities. So we we will cover JavaScript first, then deep dive into the DOM and browser APIs later on. Everything in this first article could run on the shell without any interaction with the browser APIs, just pure core JavaScript. The list below represents the general-purpose core objects defined in JavaScript:
For a complete list of the global objects, check the Global Objects page from Mozilla. Other objects you might have seen in JavaScript, like Window, CanvasRenderingContext2D, or XMLHttpRequest object or any other, have nothing to do with the JavaScript language itself and are just objects to leverage specific browser capabilities, like network access, audio, rendering and more. We will cover all of these APIs in future articles.
JavaScript today is implemented across browsers following the ECMAScript specification. As of today, five editions of ECMA-262 have been published. “Harmony”, the latest revision is a work in progress:
Edition |
Date Published |
|---|---|
| 1 | June 1997 |
| 2 | June 1998 |
| 3 | December 1999 |
| 4 | Abandoned |
| 5 | December 2009 |
| 5.1 | June 2011 |
| 6 (Harmony) | In progress |
Most browsers today support ECMAScript 5.1, the table below illustrates the conformance test suite used:
Product |
Version |
Test Suite Version |
|---|---|---|
| Chrome | 24.0.1312.57 m | ES5.1 (2012-12-17) |
| Firefox | 19 | ES5.1 (2013-02-07) |
| Internet Explorer | 10.0 (10.0.9200.16384) | ES5.1 (2012-12-17) |
| Maxthon | 3.4.2.3000 | ES5.1 (2012-08-26) |
| Opera | 12.14 (build 1738) | ES5.1 (2013-02-07) |
| Safari | 6.0.2 (8536.26.17) | ES5.1 (2012-12-17) |
There is also separate versioning for JavaScript with some additional features not necessarily implemented in ECMAScript. The latest JavaScript version is 1.8. The table below illustrates the correspondence between JavaScript and ECMAScript versions:
JavaScript version |
Relation with ECMAScript |
|---|---|
| JavaScript 1.1 | ECMA-262 - Edition 1 is based on JavaScript 1.1. |
| JavaScript 1.2 | ECMA-262 was not complete when JavaScript 1.2 was released. JavaScript 1.2 is not fully compatible with ECMA-262 - Edition 1. |
| JavaScript 1.3 | JavaScript 1.3 is fully compatible with ECMA-262 Edition 1. JavaScript 1.3 resolved the inconsistencies that JavaScript 1.2 had with ECMA-262 while keeping all the additional features of JavaScript 1.2 except == and != which were changed to conform with ECMA-262. |
| JavaScript 1.4 | JavaScript 1.4 is fully compatible with ECMA-262 Edition 1. The third version of the ECMAScript specification was not finalized when JavaScript 1.4 was released. |
| JavaScript 1.5 | JavaScript 1.5 is fully compatible with ECMA-262 Edition 3. |
Throughout this article we will be sticking to the ECMAScript 5.1 feature set, which is the latest revision implemented by all major browsers. From time to time we will have a quick look at some specific features outside the ECMAScript scope just for general information. When such features are covered it will be explicitly mentioned.
In the past years, more and more languages have been targeting JavaScript. Recently projects like Emscripten have proved that it is even possible to take native C/C++ code and compile it to JavaScript. Some people have mentioned the idea of JavaScript being the assembly language of the web. It is indeed an interesting analogy. Languages like TypeScript or Dart have demonstrated this too by cross-compiling into JavaScript.
TypeScript is an implementation of ECMAScript 6 with optional strong typing, whereas Dart is a more aggressive approach as a different language that would ideally a Dart VM for Chrome. Recently, efforts like asm.js from Mozilla have pushed the idea even further by proposing a low-level subset of JavaScript that would be targeted by compilers more efficiently. Some other initiatives like CoffeScript (often called transpilers) help developers by exposing language syntactic sugar not necessarily exposed in JavaScript today.
As we just mentioned, one of the beauty of JavaScript is that you do not have to pre-compile your code to get it to run. Your source code is loaded directly then compiled to native code at runtime by the VM using a JIT. As a developer writing JavaScript code and coming probably from a compiled language like C#, Java or ActionScript, you have to remember at all times that there will not be any optimizations done ahead of time by a static compiler. Everything will be figured out at runtime when you will be hitting refresh.
VMs like V8 introduced engines like CrankShaft which perform key optimizations at runtime like constant folding, inlining, or loop-invariant code motion that will help with performance. However, always keep in mind what you can do in your code to help with performance too. Throughout this article, we will cover key optimizations you can rely on to help your code perform better.
Memo
Feel free to use any text editor you want to write your JavaScript code. Examples in this article will be using the console from Chrome for small code samples to test things quickly. For bigger projects, WebStorm will be used. You can follow along using these tools or use your own. Here is below a set of popular tools to write JavaScript:
Let’s get started and write some code now.
As a developer reading this, you will probably want to test small things quickly and iteratively. Traditionally, when using bytecode based languages, you would type your code, hit compile, bytecode would be generated and then executed. For every modification, you would change the source code, then hit compile again and observe the changes. With JavaScript, you could be using REPL and have a way more natural and flexible way to test things and compile them on the fly. So what does REPL stands for? It stands for read-eval-print loop. Some bytecode based languages like C#, F# offer a similar functionality to easily test some pieces of your code where you can type in the command line and evaluate pieces of you code quickly and naturally.
With Chrome Developer Tools or any other console available like Firebug with Firefox, you can use the console and just start typing some code. The figure below shows the Chrome console:

When pressing enter, your code is injected and executed. In our first example, when declaring a variable, the console will just return undefined as variable declarations return no value. Just referencing the variable we declared will automatically return its value:

If we want to retrieve the string length, we also get auto-completion directly from the console:

In the figure below, we retrieve the string length:

This provides a very nice way to test quickly some pieces of your code. Note that in the Chrome developer tools console for multiline entries, you will need to use the Shift+Enter since Enter triggers code execution. In the next figure, we define a foo function then execute it:

Note that with Firebug in Firefox, the console supports multiline code in an expanded editor view where Enter creates a new line and Shift+Enter executes it. Firefox also provides ScratchPad as part of their developer tools. In ScratchPad, JavaScript multi-line code can be entered and tested interactively by just selecting the lines needed and press Shift+F4 (MacOS) or CTRL+R (Windows). The figure below shows the ScratchPad window and the console displaying the result:

Memo
If you come from other languages like C#, C++ or ActionScript, you may have been used to installing lots of tools, compilers, debuggers. One of the very cool things with JavaScript is that all your really need is a text editor and a browser. When embedded in HTML, JavaScript code can be either inlined inside a script tag:
<script> // some javascript code </script>
Or referenced and placed in external .js files, which is a better practice:
<script src="js/main.js"></script>
By default, our JavaScript code will be executed synchronously in the order the browser parses the page, from top to bottom. As a result, placing your JavaScript code at the beginning of the page is discouraged; this would cause the browser to wait until the script is executed to start displaying anything on the page. For now, we will stick to a general good practice and place our code just before the end of the body tag:
... <script src="js/main.js"></script> </body>
That way, content on the page be displayed first, and once the display list (DOM) is loaded, our code will be executed. This will also ensure that our scripts have access to the DOM and that all objects can be scripted. We will be spending some time on the order of execution of JavaScript in a future article about the DOM. HTML5 introduced some interesting new capabilities in terms of sequencing and order of JavaScript execution that we will cover too.
JavaScript is a dynamically typed language, meaning that any variable can hold any data type. If you are coming from a statically typed language, this may sound scary to you. In JavaScript there is no static typing and there will probably never be. Sadly, it is often perceived that having an explicit typing of variables is required to get type checking. It is actually not necessarily required. Types can be inferred (type-inference) automatically and propagated everywhere and provide solid code completion and type checking even with languages like JavaScript. TypeScript from Microsoft is a good example of this.
Given the absence of a typing system, JavaScript will never enforce the type of a variable, so you would not be able to rely on types to implicitly perform conversions. Remember, JavaScript does not rely on a static compiler, the VM directly interprets the source code and compiles it to native code at runtime using the JIT. To create an array in JavaScript, you could use the new keyword with the Array function constructor:
var scores = new Array();
Or simply (using the literal syntax):
var scores = [];
Note that no types are specified. At runtime the scores variable will be evaluated as an array:
var scores = []; // outputs: true console.log ( scores instanceof Array );
Because types cannot be enforced, variables can hold any type at anytime:
// store an array
var scores = [];
// store a number
scores = 5;
// store an object
scores = {};
// store a string
scores = "Hello";
If we try to call an undefined API, no errors will be captured at compile time given that there is no compilation happening statically:
var scores = []; scores.foo();
Because the foo method is not available on Array, we will get a runtime exception:
Uncaught TypeError: Object has no method 'foo'
Same thing for even the simplest object:
var myObject = {};
myObject.foo();
Which would trigger the following runtime exception:
Uncaught TypeError: Object has no method 'foo'
Browsers report errors like this one through the JavaScript console, and usually include the line that triggered the exception. The exception was uncaught in the example, but we update the code to catch it using the try catch clause:
var scores = [];
try {
scores.foo();
} catch (e) {
console.log ('API not available!');
}
We will get back to error handling soon, but for now let’s move for now on to some more essentials concepts like variable declaration.
Memo
Variables are declared using the var keyword:
var score = 12;
But omitting the var keyword will also work and declare the variable as global:
// declare a global variable score = 12;
As you can imagine, this is not recommended and you should always use var when declaring variables. So why is that? The var keyword actually dictates the scope. In the code below we use a local variable inside the foo function, making it inaccessible from outside:
function foo() {
// declare the variable locally
var score = 12;
console.log ( score );
}
function foo2() {
console.log ( score );
}
// triggers: Uncaught ReferenceError: score is not defined
foo2();
Notice that when running the code above, the error is caught at runtime; remember that there is no static compiler involved which would catch this error ahead of time. Omitting the var keyword would make the variable global to all functions:
function foo() {
// define the variable globally
score = 12;
console.log ( score );
}
function foo2() {
console.log ( score );
}
// outputs: 12
foo();
// outputs: 12
foo2();
Another important behavior when working with variables is hoisting. This behavior allows you to reference a variable before it is defined. Trying to reference an nonexistent variable will trigger an exception:
// triggers: Uncaught ReferenceError: a is not defined console.log ( a );
But, referencing a variable declared later with var works, returning its default, unset value undefined:
// outputs: undefined console.log ( a ); // variable a declared later var a = 'Hello';
What happens behind the scenes is that all the variables are moved to the top of the context block and declared first, but initialization happens where the variables are defined by our code. We will see in an upcoming section that the same behavior applies to functions too. JavaScript 1.5 introduces the concept of constants that we also have in some other languages. Constants are very important and should actually be the default in most of your programs.
Mutability is a common source of bugs. Some languages like functional programming languages rely on immutability by default. Using the keyword const will guarantee your value cannot be changed after initialization. In the code below, we define a constant named LIMIT:
// define a constant const LIMIT = 512; // outputs: 512 console.log ( LIMIT );
Note that our constant is uppercase, which is a best practice to easily spot immutability. If you try to change the value at runtime, the original value is preserved:
// define a constant const LIMIT = 512; // outputs: 512 console.log ( LIMIT ); // try to overwrite LIMIT = 45; // outputs: 512 console.log ( LIMIT );
You may be surprised that no runtime exception is triggered. Actually, some browsers do, like Firefox, since version 13. Unfortunately, as of today, the const keyword is supported in Firefox and Chrome but not in Safari, or IE 9 and 10, which dramatically reduces the reach of this feature. As a result, the const keyword should not be used if you intend to reach a broad audience and a wide variety of browsers. ECMAScript 6 defines const but with different semantics and similar to variables declared with the let statement, where constants declared as const will be block scoped (a concept we will cover in the Functions section).
Memo
As we saw earlier, because of JavaScript’s dynamic nature, types cannot be enforced. This can be a limitation for debugging, because any variable can basically hold any type, you may be taken by surprise if, for instance, no runtime exception will be triggered due to an implicit runtime conversion failing. JavaScript actually performs implicit type conversions at runtime at different occasions. First, when using numeric and string values with the + operator, the String type has precedence and concatenation is always performed:
// gives: "3hello"; var a = 3 + "hello"; // gives: "hellotrue" var b = "hello" + true;
When using other arithmetic operators, the Number type has precedence:
// outputs: 9 var a = 10 - "1"; // outputs: 20 var b = 10 * "2"; // outputs: 5 var c = 10 / "2";
Implicit conversions to Number will also happen when using the == or != operators with the Number, String and Boolean types:
// outputs: true
console.log ("1" == 1); // equals to 1 == 1
// outputs: true
console.log ("1" == true); // equals to 1 == 1
// outputs: false
console.log ("1" != 1); // equals to 1 != 1
// outputs: false
console.log ("1" != true); // equals to 1 != 1
// outputs: false
console.log ("true" == true); // equals to NaN == 1
To avoid implicit conversions and verify that both types and values are equal, you can rely on the strict equality (===) or strict inequality (!==) operators, which will never perform automatic conversion implicitly:
// outputs: false
console.log ("1" === 1);
// outputs: false
console.log ("1" === true);
// outputs: true
console.log ("1" !== 1);
// outputs: true
console.log ("1" !== true);
It is therefore a good practice to use the strict operators to reduce the risks of ambiguity. If we need to convert data explicitly, we can use the appropriates types conversion functions:
// convert a string to a number
var a = Number ("3");
// convert a boolean to a number
var b = Number (true);
// tries to convert a non numeric string to a number
var c = Number ("Hello");
// outputs: 3 1 "NaN"
console.log ( a, b, c );
In the same way, converting a string to a number can be done using the parseInt and parseFloat functions:
// convert a string to a number var a = parseInt ( "4 chicken" ); // convert a boolean to a number var b = parseFloat ( "1.5 pint" ); // outputs: 4 1.5 console.log ( a, b );
We saw earlier that JavaScript can throw runtime exceptions, let’s spend a few minutes on this now.
Memo
In all projects we have to deal with runtime exceptions. In JavaScript, as we saw earlier, these can be triggered by the runtime itself or explicitly by our code. For example, if you try to call a method not available on an object, this will trigger a runtime exception:
var scores = []; // triggers: Uncaught TypeError: Object has no method 'foo' scores.foo();
At any time, if we need to throw an exception ourselves, we can use the throw keyword with Error object:
throw new Error ('Oops, there is a problem');
As expected, a runtime exception needs to be handled otherwise the console will output the following message:
Uncaught Error: Oops, there is a problem
To handle errors, we can use the try catch statement. The message property in thrown Errors contains the error message:
try {
throw new Error ('Oops, there is a problem');
} catch ( e ) {
// outputs: Oops, there is a problem catched!
console.log ( e.message + ' catched!');
}
If we need some logic to be executed whether or not an error is thrown after code has executed in the try block, we use the finally statement:
try {
throw new Error ('Oops, there is a problem');
} catch ( e ) {
// outputs: Oops, there is a problem catched!
console.log ( e.message + ' catched!');
} finally {
// outputs: Code triggered at all times
console.log ( 'Code triggered at all times' );
}
Note that conditional catch cannot be done the same way as in languages like ActionScript or C#, by placing the appropriate type in the catch block to redirect the exception automatically. In JavaScript we use a single catch block and have the appropriate type test inside that same block:
try {
throw new Error ('Oops, there is a problem');
} catch ( e ) {
if ( e instanceof BufferError ) {
// handle buffer error
} else if ( e instanceof ParseError ) {
// handle parse error
}
} finally {
// outputs: Code triggered at all times
console.log ( 'Code triggered at all times' );
}
Note that the JavaScript specification details the ability to inline the if directly inside the catch block.
try {
throw new Error ('Oops, there is a problem');
} catch ( e if e instanceof BufferError ) {
// handle buffer error
} catch ( e if e instanceof ParseError ) {
// handle parsing error
} finally {
// outputs: Code triggered at all times
console.log ( 'Code triggered at all times' );
}
Unfortunately, this feature is not part of the ECMAScript specification and will not work in most browsers except Firefox, which again has excellent support for the latest JavaScript’s features. You can rely on Firefox for testing this feature, but don’t rely on it for a real project. What about performance? In JavaScript, exception handling does not have much impact on performance either, except if you use try catch inside a function. So make sure you don’t do this:
function test() {
try {
var s = 0;
for (var i = 0; i < 10000; i++) s = i;
return s;
} catch ( e ) {};
}
But instead, move the try catch outside of the function:
function test() {
var s = 0;
for (var i = 0; i < 10000; i++) s = i;
return s;
}
try {
test();
} catch ( e ) {};
Next, let’s have a look now at the different types of data we will be working with in JavaScript, composite and primitive data types.
Memo
JavaScript defines six data types, and just like in most languages, you can divide these in two categories:
As expected, primitives are copied by value:
var a = "Sebastian"; var b = "Tinic"; var c = a; a = "Chris"; // outputs: Sebastian console.log ( c );
Composite (objects) are everything else, like a Window object, a RegExp, a function, etc. and passed by reference. The example below illustrates the idea:
// create an Array var a = ['Sebastian', 'Alex', 'Jason']; // create an Array var b = ['Sebastian', 'Alex', 'Jason']; // outputs: false console.log ( a == b );
Even though the two arrays contain the exact same values, we are actually comparing two different pointers here, not two similar values. In the code below, we illustrate this differently:
// create an Array var a = ['Sebastian', 'Alex', 'Jason']; // pass by reference (nothing is copied here) // b points now to a var b = a; // modifying b modifies a b[1] = 'Scott'; // outputs: ["Sebastian", "Scott", "Jason"] console.log ( a );
Before jumping into the specific behaviors of JavaScript, let’s have a look at the Boolean type now.
Memo
The concept of Booleans is probably the easiest part of any language. However it is worth nothing a few things when it comes to JavaScript. The code below highlights how primitives behave when tested as Booleans:
var a = true; var b = "true"; var c = 1; var d = false; // outputs: true console.log ( a == true ); // outputs: false console.log ( b == true ); // outputs: true console.log ( c == true ); // outputs: false console.log ( d == true );
Did you notice the implicit conversion performed here? Like on most languages, you can convert anything to a Boolean by using the Boolean conversion function or Boolean function constructor:
var a = new Boolean ( true ); var b = new Boolean ( "true" ); var c = new Boolean ( "false" ); var d = new Boolean ( 1 ); var e = new Boolean ( false ); var f = new Boolean ( undefined ); var g = new Boolean ( null ); // outputs: true console.log ( a == true ); // outputs: true console.log ( b == true ); // outputs: true console.log ( c == true ); // outputs: true console.log ( d == true ); // outputs: false console.log ( e == true ); // outputs: false console.log ( f == true ); // outputs: false console.log ( g == true );
Note that we are using the Boolean constructor here, producing Boolean objects, not the Boolean conversion function. producing primitives. Finally, any type placed inside a conditional expression will be converted to Boolean. In the code below, our test succeeds and displays the message in the console:
// converts automatically "false" to new Boolean("false")
if ( "false" ) {
console.log ("This will be triggered!")
}
Memo
In JavaScript, there is no such concept of int, uint or float, so in case of decimals, everything is a number. The type number is used for all decimals and is represented as a float and using 64-bit floating point format in memory:
var a = 4; var b = 6.9; var c = -5; // outputs: number number number console.log ( typeof a, typeof b, typeof c);
Division by zero or overflow and underflow do not trigger exceptions, it just happens silently:
// division by zero var a = 0 / 0; // number too big var b = Number.POSITIVE_INFINITY; // number too big var c = Number.NEGATIVE_INFINITY; // outputs: NaN Infinity -Infinity console.log ( a, b, c );
It is worth noting that NaN cannot be compared to NaN:
// outputs: false console.log (Number.NaN == Number.NaN);
But the isNaN function can be used:
// outputs: true console.log ( isNaN (Number.NaN) );
It is time to talk now about one of the most important core object in JavaScript, the Object type.
Memo
To create a simple object, we rely on the Object type. Object is in fact pretty much the core of everything in JavaScript. We will come back to this in a few minutes. It is sometimes useful to quickly define an object that would hold a few properties, note that both syntaxes are possible, literal and nonliteral (function constructor):
// custom object with literal syntax
var person = { name: 'Bob', lastName: 'Groove' };
// custom object with new (object constructor)
var person = new Object();
// create some properties
person.name = 'Bob';
person.lastName = 'Groove';
Obviously, the first syntax is shorter and is usually preferred.
// custom object
var person = {};
// create a new property name
person.name = ‘Bob’;
Using the bracket notation also works in case you need to evaluate the property dynamically. Keep in mind that this syntax is slightly slower and should not be used by default. This also makes refactoring harder.
// custom object
var person = {};
var prop = "name";
person [prop] = 'Bob';
Which equals to the dot operator syntax:
// custom object
var person = {};
person.name = 'Bob';
// outputs: true
console.log ( person.name == person['name'] );
Note that property access in general tends to be slow and should be minimized. V8 is known to provide fast property access based on a different way it stores object properties. Other VMs use a hashmap to lookup for properties; V8 is using an array approach using hidden classes. The hidden class is used for objects of the same type which stores the offset to access properties values instead of searching through an hash table.
To test if a property is defined on an object, we can use the in operator:
// custom object
var person = { name: 'Bob', lastName: 'Groove' };
// outputs: true
console.log ( "name" in person );
Note that the in keyword will also search for inherited properties through the prototype chain:
// custom object
var person = { name: 'Bob', lastName: 'Groove' };
// outputs: true
console.log ( "toString" in person );
The hasOwnProperty() API will not check through the prototype chain and only for direct custom properties:
// custom object
var person = { name: 'Bob', lastName: 'Groove' };
// outputs: false
console.log ( person.hasOwnProperty ("toString") );
// outputs: true
console.log ( person.hasOwnProperty ("name") );
By default, all instance properties are dynamic and can be deleted using the delete keyword:
// custom object
var person = {};
// add a new property
person.age = 40;
// delete it
delete person.age;
// try to retrieve it
// outputs: undefined
console.log(person.age);
Because of the underlying mechanics of some VMs like V8 (Chrome) it is not recommended to delete an object property. Doing so will alter the structure of the hidden class and have a performance hit. If you don’t need a property anymore, set it to null but don’t delete it. ECMAScript 5 introduced a set of APIs to allow finer control over object extensions and property attributes. If we want to make sure no properties get added to an object, we can use the Object.preventExtensions() API:
// custom object
var person = { name: 'Bob', lastName: 'Groove' };
// prevents any extensibility
Object.preventExtensions(person);
// set the age
person.age = 25;
// outputs: undefined
console.log ( person.age );
// delete the name property
delete person.name;
// outputs: undefined
console.log ( person.name );
Given that methods on objects are in fact properties referencing functions, our object cannot be augmented with any methods either, however, our object can still get its properties deleted. At anytime we can test if the object is extensible or not by using the Object.isExtensible() API:
// custom object
var person = { name: 'Bob', lastName: 'Groove' };
// prevents any extensibility
Object.preventExtensions(person);
// outputs: false
console.log ( Object.isExtensible ( person ) );
If we want to prevent from any extensibility or deletion, we can also seal the object through the Object.seal() API. Once an object is sealed, existing properties can still be changed and retrieved, but new ones cannot be added and deletion is also forbidden:
// custom object
var person = { name: 'Bob', lastName: 'Groove' };
// we seal our object
Object.seal ( person );
// outputs: Bob
console.log ( person.name );
// attempt to null the property
person.name = null;
// outputs: null
console.log ( person.name );
// change the name
person.name = "David";
// outputs: David
console.log ( person.name );
// attempt to create a new property
person.age = 30;
// outputs: undefined
console.log ( person.age );
// attempt to delete the property
delete person.name;
// outputs: David
console.log ( person.name );
Finally, we can resort to the Object.freeze() API if we truly want to ensure immutability at all levels:
// custom object
var person= { name: 'Bob', lastName: 'Groove' };
// we freeze our object
Object.freeze ( person );
// attempt to change the name value
person.name = "David";
// outputs: Bob
console.log ( person.name );
// attempt to delete the property
delete person.name;
// outputs: Bob
console.log ( person.name );
// attempt to null the property
person.name = null;
// outputs: Bob
console.log ( person.name );
To test if any object is either sealed or frozen we can rely on the Object.isSealed() and Object.isFrozen() APIs:
// outputs: true console.log ( Object.isSealed (person) ); // outputs: true console.log ( Object.isFrozen (person) );
Note that an object can be sealed and frozen at the same time and that once sealed or frozen, you cannot undo it. To summarize:
If we need to go at a more granular level, we can actually know more about each property through the Object.getOwnPropertyDescriptor() API which returns a property descriptor. In the code below, we retrieve a descriptor for the person property:
// custom object
var person = { name: 'Bob', lastName: 'Groove' };
// retrieve the property descriptor for ‘name’
var desc = Object.getOwnPropertyDescriptor(person, 'name');
// outputs: true
console.log(desc.writable);
// outputs: true
console.log(desc.configurable);
// outputs: true
console.log ( desc.enumerable );
// outputs: "Bob"
console.log(desc.value);
A property inspector has the following properties:
By default, all properties are configurable, enumerable and writeable but configurability is modified if we seal our object:
// custom object
var person = { name: 'Bob', lastName: 'Groove' };
// we seal the object
Object.seal ( person );
// retrieve the property descriptor for ‘name’
var desc = Object.getOwnPropertyDescriptor(person, 'name');
// outputs: true
console.log(desc.writable);
// outputs: false
console.log(desc.configurable);
// outputs: true
console.log ( desc.enumerable );
// outputs: "Bob"
console.log(desc.value);
If we freeze it, then everything is locked except enumeration:
// custom object
var person = { name: 'Bob', lastName: 'Groove' };
// we freeze the object
Object.freeze ( person );
var desc = Object.getOwnPropertyDescriptor(person, 'name');
// outputs: false
console.log(desc.writable);
// outputs: false
console.log(desc.configurable);
// outputs: true
console.log ( desc.enumerable );
// outputs: "Bob"
console.log(desc.value);
Sealing or freezing an object can be useful in scenarios where you want to ensure some level of immutability in parts of your program. Like we just saw, the Object.getOwnPropertyDescriptor() API returns attributes about any property, you may wonder if it is possible to define a new property and at the same time its attributes? Yes, that is possible too. Up until now, we defined new properties using the dot operator:
myObject.foo = myValue;
Using this syntax is actually a shortcut and makes properties by default enumerable, configurable and writeable. ECMAScript 5 defines a more granular API called Object.defineProperty(), which allows you to define the property attributes using a property descriptor. The API has the following signature:
Object.defineProperty(obj, prop, descriptor)
In the code below, we create a name property and make it writeable, enumerable and configurable:
// custom object
var myObject = {};
Object.defineProperty(myObject, "name", {value : 'Bob',
writable : true,
enumerable : true,
configurable : true});
// outputs: Bob
console.log ( myObject.name );
Given that we set all attributes to true, we can enumerate the property, modify it and even delete it:
// custom object
var myObject = {};
// we create the property name with specific attributes
Object.defineProperty(myObject, "name", {value : 'Bob',
writable : true,
enumerable : true,
configurable : true});
// outputs: Bob
console.log ( myObject.name );
// outputs: name
for ( var p in myObject ) {
console.log ( p );
}
// we update the name
myObject.name = 'Stevie';
// outputs: Stevie
console.log ( myObject.name );
// we delete the property
delete myObject.name;
// outputs: undefined
console.log ( myObject.name );
If we change the attributes, we can be very granular and prevent any configuration or update but still allow enumeration:
// custom object
var myObject = {};
// we create the property name with specific attributes
Object.defineProperty(myObject, "name", {value : 'Bob',
writable : false,
enumerable : true,
configurable : false});
// outputs: Bob
console.log ( myObject.name );
// outputs: name
for ( var p in myObject ) {
console.log ( p );
}
// write access fails silently
myObject.name = 'Stevie';
// deletion fails silently
delete myObject.name;
// outputs: Bob
console.log ( myObject.name );
Even more powerful, if we use the get and set attributes as part of the descriptor object, we can define the implementation of getters and setters using the same API:
// custom object
var myObject = {};
// we define the getter
function getter() {
return this.nameValue;
}
// we define the setter
function setter(newValue) {
this.nameValue = newValue;
}
// we create the property name with specific attributes
Object.defineProperty(myObject, "name", {
get: getter,
set: setter});
// we change the value
myObject.name = 'Stevie';
// outputs: Stevie
console.log ( myObject.name );
We define the getter and setter for our name property. Note that we use the nameValue alias to reference the property, but we can actually use any value, using foo would work just fine.
// we define the getter
function getter() {
return this.foo;
}
// we define the setter
function setter(newValue) {
this.foo = newValue;
}
We now have control over how our value is read or written. In the code below, we make sure that any string read from the name property will always be cased correctly:
// we define the getter
function getter() {
return this.nameValue.charAt(0).toUpperCase()+this.nameValue.substr(1).toLowerCase();
}
In the code below, we use a non case sensitive string, when we retrieved the value, the string is correctly formatted:
// custom object
var myObject = {};
// we define the getter
function getter() {
return this.nameValue.charAt(0).toUpperCase()+this.nameValue.substr(1).toLowerCase();
}
// we define the setter
function setter(newValue) {
this.nameValue = newValue;
}
// Example of an object property added with defineProperty with a data property descriptor
Object.defineProperty(myObject, "name", {
get: getter,
set: setter});
// we change the value
myObject.name = 'stevie';
// outputs: Stevie
console.log ( myObject.name );
Pretty powerful right? Note that the Object class also defines a defineProperties() API, allowing you to define multiple properties all at once. Finally, to enumerate properties from an object, we can rely on the Object.keys() API:
// custom object
var person = { name: 'Bob', lastName: 'Groove' };
// outputs: ["name", "lastName"]
console.log ( Object.keys ( person ) );
You may wonder if immutability makes property access faster? Unfortunately, no. It is important to note that these APIs to seal, freeze or prevent extensions of objects have been slow in the past and have made property access slower. Recent benchmarks have shown that performance got much better recently, but keep an eye on them in terms of performance impact.
Memo
In JavaScript, almost everything is an Object. Let’s try the code below to illustrate this:
function foo(){};
// outputs: true
console.log ( foo instanceof Object );
var countries = ['USA', 'FRANCE'];
// outputs: true
console.log ( countries instanceof Object );
var person = { name: "Bob", lastName: "Groove" };
// outputs: true
console.log ( person instanceof Object );
As expected, these composites types are of type Object. Even function, we will get back to that later in this article. But what about primitives, like a string, a decimal or a Boolean?
var result = true; // outputs: false console.log ( result instanceof Object ); var name = 'Bob'; // outputs: false console.log ( name instanceof Object ); var score = 190; // outputs: false console.log ( score instanceof Object );
So you may wonder then how come these types have methods defined on them? Like calling length on a String:
var name = 'Bob'; // outputs: 3 console.log ( name.length );
Behind the scenes a wrapping object will be created when methods are called on primitives. This concept is known as ‘boxing’. At runtime, the code above will actually generate the following internally:
// outputs: 3 console.log ( (new String (name)).length );
That wrapper object (acting as a box here) is then discarded and garbage collected once the length getter is called. That is why trying to store data on a primitive fails. The temporary object we are writing into is immediately discarded. Trying to retrieve our property later on will create another box and as a result return undefined:
var name = 'Bob'; // write some data name.foo = 'Some Data'; // equals to (new String (name)).foo = 'Some Data'; // outputs: undefined console.log ( name.foo ); // equals to console.log ( (new String (name)).foo );
But storing data on a primitive created with a function constructor is possible, because no implicit boxing/unboxing occurs:
// create the string with new (function constructor)
var name = new String("Bob");
// write some data
name.foo = "Some Data";
// outputs: Some Data
console.log(name.foo);
Today's JavaScript VMs are pretty fast at boxing/unboxing. It is not worth worrying too much about it performance wise.
Two other types are not of type Object, null and undefined. The code below demonstrates this:
// outputs: false console.log ( null instanceof Object ); // outputs: false console.log ( undefined instanceof Object );
Memo
As we just saw, null and undefined are a special kind of types. In JavaScript, any variable not initialized is undefined:
var myObject; var i; // outputs: undefined undefined console.log ( myObject, i );
Same for undefined properties:
var myObject = { name: "Bob" };
// outputs: undefined
console.log ( myObject.firstName );
Some typed languages sometimes initialize primitives values or objects to null. This allows developers to use null for initialization testing. Automatic initialization to null by the runtime cannot happen in JavaScript, keep this in mind at all times. If you forget, you may be tempted to use lots of null checks in your code like in the example below:
var myArray;
// if the Array is not initialized, then initialize it
if ( myArray == null ) {
myArray = new Array();
console.log ('Array initialized');
} else console.log ('already created');
The issue is that our test for null here is not truly reliable. Remember, our Array is not initialized, hence returns undefined. On top of that, null and undefined are two different types but resolve to true when compared when we are not using the strict equality operator:
// outputs: object undefined console.log ( typeof null, typeof undefined ); // outputs: true console.log ( undefined == null );
Remember about implicit conversions? We are using here the == operator. If were to use the strict equality operator (===), which tests for both type and value, our test would fail:
// outputs: false console.log ( undefined === null );
Remember we used the strict operators earlier to resolve ambiguity. Here again, it proves to be useful. In our previous code we would now be entering the else block:
var myArray;
// if the Array is not initialized, then initialize it
if ( myArray === null ) {
myArray = new Array();
console.log ('Array initialized');
} else console.log ('already created');
You could also just rely on a Boolean evaluation and do a simple if not:
var myArray;
// if the Array is not initialized, then initialize it
if ( !myArray ) {
myArray = new Array();
console.log ('Array initialized');
} else console.log ('already created');
Note that internally, that test will evaluate to:
if ( !Boolean(undefined) )
But in order to stay consistent with what we initially tried, it is a good practice to just set our variable to null, to explicitly emphasize that it is not initialized but expected to be later on:
// initialize to null
var myArray = null;
// if the Array is not initialized, then initialize it
if ( myArray == null ) {
myArray = new Array();
console.log ('Array initialized');
} else console.log ('already created');
Our code becomes now truly reliable even when using strict equality:
// initialize to null
var myArray = null;
// if the Array is not initialized, then initialize it
if ( myArray === null ) {
myArray = new Array();
console.log ('Array initialized');
} else console.log ('already created');
If we now run our code, it outputs:
Array initialized
Let’s have a look at loops now.
Memo
Loops are an essential part of any programming language. JavaScript supports all the basics kinds of loops you would expect like for, for in, while or do while:
var lng = 200;
// classic for
for ( var i = 0; i < lng; i++ ) {
}
var myObject = { name: "Bob", age : 30 };
// object enumeration
for ( var p in myObject ) {
/* outputs:
name : Bob
age : 30
*/
console.log ( p, " : ", myObject[p] );
}
var i = 0;
// while loop
while ( i < lng ) {
console.log ( i );
i++;
}
// do while loop
do {
console.log ( i );
i++;
} while ( i < lng )
Some other languages provide also support for a for each loop. In JavaScript, we will be using a more functional approach for this and use the Array.forEach() API which we will cover shortly. It is important to note that when using the for in loop to enumerate object properties, because ECMA-262 does not specify the enumeration order, it is implementation dependent and the general behavior across most browsers is to match the definition order.
// custom object
var myObject = { name: "Bob", age: 20 };
// enumerate
for ( var p in myObject ) {
/*
// outputs:
name
age
*/
console.log ( p );
}
If we change the order of definition, it gets reflected in the enumeration:
// custom object
var myObject = { age: 20, name: "Bob" };
// enumerate
for ( var p in myObject ) {
/*
// outputs:
age
name
*/
console.log ( p );
}
There is one exception though, if you have numerical properties as strings, these will be listed ahead of the non-numerical ones.
// custom object
var myObject = { age: 20, name: "Bob", "12":"2343" };
// enumerate
for ( var p in myObject ) {
/*
// outputs:
12
age
name
*/
console.log ( p );
}
In terms of performance, the for in loop tend to be slow, make sure you don’t rely on it heavily when performance is a key requirement.
Memo
As developers, we are probably using arrays all the time in the content we develop. We use them all the time, to store, reference, loop, iterate, pretty much everywhere. In the code below, we create an array and initialize its length through the constructor:
// create an Array var myArray = new Array(5); // outputs: 5 console.log ( myArray.length );
Note that with one more argument, the Array constructor adds those values to the array instead:
// create an array var myArray = new Array(5, 10, 30, 20); // outputs: [5, 10, 30, 20] console.log ( myArray );
If we were to set the length to a larger number than the size of the array, undefined values would be padded:
// create an Array var myArray = new Array(5); // outputs: 5 console.log ( myArray.length ); // increase the array size myArray.length = 7; // outputs: undefined console.log ( myArray[6] );
In the same way, adding extra commas will add undefined values to the array:
// create an Array var myArray = ["Bob", "James", , "Tom"]; // outputs: 4 console.log ( myArray.length ); // outputs: undefined console.log ( myArray[2] );
Array is also an object and can act like a map. In the code below, we create a dynamic property on it. Named, non-numeric properties do not affect array length:
var myArray = []; // create a custom dynamic property myArray['name'] = 'Bob'; // outputs: 0 console.log(myArray.length); // outputs: Bob console.log(myArray['name']);
At this point, an array is almost identical to a plain object. The APIs used on Array are very similar to what you would find on other languages. You can expect all the mutator and accessor APIs you may have used in the past like pop(), push(), splice(), etc.:
// create an Array var myArray = new Array(200); // outputs: 200 console.log ( myArray.length ); // push one element myArray.push ( 50 ); // outputs: 201 console.log ( myArray.length );
But the list does not stop here. ECMAScript 5.1 introduced a set of iteration APIs on the Array object, The list below illustrates all of them and some examples on how they can be used:
// some values
var values = [1, 2, 3]
/*
outputs:
1
2
3
*/
values.forEach(function(item) { console.log ( item ) });
var data = [ 12, "bobby", "willy", 58, "ritchie" ];
function every ( element, index, source ) {
return ( element instanceof Number );
}
// is this an Array containing numbers only?
var onlyNumbers = data.every ( every );
// outputs : false
console.log( onlyNumbers );
var users = [ { prenom : "Bobby", age : 18, sexe : "H" },
{ prenom : "Linda", age : 18, sexe : "F" },
{ prenom : "Ritchie", age : 16, sexe : "H"},
{ prenom : "Stevie", age : 15, sexe : "H" } ]
function some ( element, index, source ) {
return ( element.sexe == "F" );
}
// is there a female in this Array?
var result = users.some ( some );
// outputs : true
console.log ( result );
var users = [ { name : "Bobby", age : 18 },
{ name : "Willy", age : 21 },
{ name : "Ritchie", age : 16 },
{ name : "Stevie", age : 21 } ];
function filter ( element, index, source ) {
return ( element.age >= 21 );
}
var legalUsers = users.filter ( filter );
function browse ( element, index, source ) {
console.log ( element.name, element.age );
}
/* outputs :
Willy 21
Stevie 21
*/
legalUsers.forEach( browse );
var names = ["bobby", "willy", "ritchie"];
function map ( element, index, source ) {
return element.charAt(0).toUpperCase()+element.substr(1).toLowerCase();
}
// we create an array from the result of the map function
var formattedNames = names.map ( map );
// outputs : Bobby Willy Ritchie
console.log ( formattedNames );
var values = [20, 30, 40, 50];
function reduce ( previousValue, currentValue, index, source ) {
return previousValue + currentValue;
}
// we create a table that holds the reduction
var reduced = values.reduce ( reduce );
// outputs : 140
console.log ( reduced );
var values = [20, 30, 40, 50];
function reduce ( previousValue, currentValue, index, source ) {
return previousValue + currentValue;
}
// we create a table that holds the reduction
// reduceRight starts from the right
var reduced = values.reduceRight ( reduce );
// outputs : 140
console.log ( reduced );
Even though these APIs are really powerful, they tend to be slow. Here again, if performance is a key requirement, do not rely on them too heavily. For instance, the map function could be replaced by the following code:
var names = ["bobby", "willy", "ritchie"];
var lng = names.length;
for (var i = 0; i < lng; i++) {
var item = names[i];
names[i] = item.charAt(0).toUpperCase() + item.substr(1).toLowerCase();
}
This version even though less pretty, will perform much faster. So why is that? A few reasons behind this:
JavaScript does not have support for dictionaries. In the code below, we use a simple object to map to another one containing positioning information:
// create an Array
var myArray = [];
// an object key
var key = {}
// map the canvas to a custom literal object
myArray[key] = { x : 400, y : 400};
// outputs: Object {x: 400, y: 400}
console.log(myArray[key]);
This example could lead you to the conclusion that arrays can be used as a dictionary. What happens behind the scenes is that the object is converted to a string, which equals to the creation of an [object Object] property:
// map the canvas to a custom literal object
myArray[key] = { x : 400, y : 400}; // equals to: myArray["[object Object]"] = { x : 400, y : 400};
When dealing with arrays, performance is usually a common topic. In the following section, we are going to spend some time on performance optimizations regarding arrays. In the code below we loop over the array elements:
// some names
var names = ["Daniel", "Divya", "Veronique"];
// store the length
var lng = names.length;
/* outputs:
Daniel
Divya
Veronique
*/
for (var i = 0; i < lng; i++) {
var name = names[i];
}
Note that we cached the length of the array in the lng variable instead of reevaluating the length for each iteration. This is good practice you may want to follow. Re-evaluating the length every time can have an impact on performance. Also, because of its succinctness, the literal syntax is usually favored to create objects like an array:
// empty array
var data = [];
for (var i = 0; i < 1000000; i++) {
data[i] = i;
}
Note that our array is empty, we do not pre-allocate it with a specific length. However, some VMs like V8 or SpiderMonkey prefer non-pre allocated arrays, and the code above will perform actually faster than the code below:
var lng = 500000;
// slower than using [] or new Array()
var data = new Array(lng);
for (var i = 0; i < lng; i++) {
data[i] = i;
}
We are talking about a 5 or 10% performance increase, but still. It is also not recommended to use mixed types inside an array. Even though pretty uncommon, be aware that this will obviously force the VM to react to this and spend time handling unexpected types and convert them. In the code below we calculate the sum of the values:
// some values of the same type
var values = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var sum = 0;
var lng = values.length;
for ( var i = 0; i< lng; i++ ) {
sum += values [ i ];
}
Now, if we were to have multiple types inside the array, this code would perform slower:
// some mixed types
var values = [ 1, 2, "3", 4, 5, 6, 7, 8, 9, "10"];
var sum = 0;
var lng = values.length;
for ( var i = 0; i< lng; i++ ) {
sum += values [ i ];
}
Also, avoid having holes in your arrays too, which can be caused by the use of delete or just setting a specific index to null:
// some scores var scores = [200, 100, 456, 231, 800, 453]; // create a hole scores [2] = null; // create another hole delete scores [4];
Note that using the length property is also an efficient way to empty an array. A typical scenario is inside a loop, where you could be tempted to allocate a new array to reset it. Rather than recreate an empty instance every time which would be costly on time and memory, we can just set its length to 0:
// create an Array var myArray = new Array(5); // outputs: 5 console.log ( myArray.length ); // empties the array myArray.length = 0; // outputs: 0 console.log ( myArray.length );
Finally, when indexing elements from an array, store the value into a local variable and avoid using the array syntax (brackets notation) which is slow, so instead of writing the following code:
for ( var i = 0; i< lng; i++ ) {
myArray[i].x = Math.random()*500;
myArray[i].y = Math.random()*500;
myArray[i].friction = Math.random();
}
It is preferred to write:
for ( var i = 0; i< lng; i++ ) {
// store a reference in a local variable
var element = myArray[i];
element.x = Math.random()*500;
element.y = Math.random()*500;
element.friction = Math.random();
}
In addition to iteration APIs, JavaScript 1.7 introduced proper iterators. Let’s have a look at them.
Memo
JavaScript 1.7 introduced iterators, through the Iterator object. Iterators are really useful and allow developers to reduce the number of states introduced by iteration. Originally, without any iterators, looping through an array in JavaScript look like this:
var countries = [ 'France', 'USA', 'Japan' ];
var lng = countries.length;
for ( var i = 0; i< lng; i++) {
// outputs:
France
USA
Japan
console.log ( countries[i] );
}
Notice the number of variables defined here, a variable i is incremented, tested against a maximum length, and the use of the variable i to index our array, lots of places where things could go wrong. How could we reduce this to the maximum and write safer code? This is where iterators come to the rescue:
// some data var countries = [ 'France', 'USA', 'Japan' ]; // create the Iterator through the Iterator function var it = Iterator(countries); // outputs: [0, "France"] console.log ( it.next() ); // outputs: [1, "USA"] console.log ( it.next() ); // outputs: [2, "Japan"] console.log ( it.next() );
Thanks to iterators, less variables are defined, we use query the next item from our Iterator object, that’s all. But remember, Iterators are for now only available as part of JavaScript 1.7, not ECMAScript. As a result, Chrome or IE do not support such a feature, only Firefox. This basically prevents you from using iterators in projects where reach matters.
Memo
The Date class returns information about the current time, but is also very commonly used for benchmarking purpose using the Date.now() API. The example below illustrates the idea:
var start = Date.now();
var iterations = 50000000;
var buffer = new Array(iterations);
for(var i = 0; i < iterations; i++) {
buffer[i] = i;
}
// outputs: 2703
console.log(Date.now() - start);
We capture the time (ms) before the code we want to benchmark is triggered, once finished we compare the two. Note that iterating over this array takes around 3 seconds today in Chrome 24 and around 2 seconds in Safari 6 and Firefox 18 on MacOS. The use of a Date object to calculate performance is the most popular way to benchmark JavaScript code, but some more advanced techniques are being used today too. Here are some of the limitations of the Date.now() approach:
To get more granular performance metrics, we can rely on the new performance.now() API part defined on the performance property. This API returns a floating point since the page started loading providing microseconds in the fractional, which can be very useful for benchmarking. Let’s have a quick look at the difference:
// outputs: 1359349137666 console.log( Date.now() ); // outputs: 22.16799999587238 console.log ( window.performance.now() );
If we change our previous benchmark to use the performance.now()API, we get a more granular number:
var start = window.performance.now();
var iterations = 50000000;
var buffer = new Array(iterations);
for(var i = 0; i < iterations; i++) {
buffer[i] = i;
}
// outputs: 3303.2060000114143
console.log(window.performance.now() - start);
This API is part of the navigation timing feature available now in Chrome, Firefox and IE9 but unfortauntely not Safari or Opera. We will come back to this feature in a future article to study sequencing around loading and initialization.
Memo
JavaScript has support for first-class functions, which means they can be passed as parameters to other functions, or be returned, assigned to variables and stored into arrays. Actually, functions can be declared three ways, as named, as an expression or anonymous:
// named function
function sayHello () {
console.log('Hello');
}
// function expression
var sayHello = function() {
console.log ('Hello');
}
// anonymous function used as the listener
button.addEventListener ("click", function (e) {
console.log ( e.currentTarget );
})
One first difference between the two is hoisting. Remember we saw previously that behavior with hoisting of variables. With functions, the named definition is always interpreted first, so if we call sayHello() before defining it, it will just work:
// outputs: First definition
sayHello();
// named function
function sayHello () {
console.log('First definition');
}
// function expression
var sayHello = function() {
console.log ('Second definition');
}
// outputs: Second definition
sayHello();
Because named functions are interpreted first, function expressions always have precedence over named functions:
// function expression
var sayHello = function() {
console.log ('First definition');
}
// named function
function sayHello () {
console.log('Second definition');
}
// outputs: First definition
sayHello();
Finally, named functions cannot be renamed, whereas with a function expression, the variable pointing to it can be renamed.
Note that we can simply inline the call right after its definition, this technique called an immediately invoked function expression (or IIFE) allows us to define the function and trigger it at the same time:
// named function with call inlined
(function sayHello() {
console.log('First definition');
}());
Note that this syntax can also be useful to prevent from polluting the global scope (Window). By declaring variables with var inside a function, these definitions will be scoped only inside the function. In the code below, we only expose a global entry point through the getUsers function, other functions will behave as private:
(function () {
getUsers = function () {
// entry point exposed to the global namespace
return 'getting users';
}
var checkTime = function () {
// logic to check time
}
var authenticate = function () {
// logic for authentication
}
}());
// outputs: getting users
console.log ( getUsers() );
// triggers: Uncaught ReferenceError: checkTime is not defined
console.log ( checkTime() );
Note that the getUsers definition is now global. If we want even better control, we can rely on the reveal module pattern:
var module = (function () {
var getUsers = function () {
// entry point exposed to the global namespace
return 'getting users';
}
var checkTime = function () {
// logic to check time
}
var authenticate = function () {
// logic for authentication
}
return {
getUsers:getUsers
}
}());
// outputs: getting users
console.log ( module.getUsers() );
// triggers: Uncaught ReferenceError: checkTime is not defined
checkTime();
Through this pattern, we no longer rely on a global definition. We externalize safely the definitions we want to make public or not, without ever polluting the global scope.
Let’s have a look now at a function itself and what we can do with it:
function calculate(a, b, c){};
// grab the number of parameters
// outputs: 3
console.log (calculate.length);
// store data
calculate.x = 12;
// retrieve it
// outputs: 12
console.log (calculate.x);
As we saw earlier, functions are objects, and like with arrays, we can use the brackets syntax to access or write properties, which can be useful if we need to evaluate the properties dynamically:
function calculate(a, b, c){};
// grab the number of parameters
// outputs: 3
console.log (calculate.length);
// store data
calculate['x'] = 12;
// retrieve it
// outputs: 12
console.log (calculate['x']);
We can also easily access all the parameters passed to a function using the arguments array:
function average() {
var total = 0;
var lng = arguments.length;
for ( var i = 0; i< lng; i++ ) {
total += arguments [ i ];
}
return total / lng;
}
// outputs: 263.5
console.log ( average ( 10, 29, 893, 122 ) );
All functions create a local variable arguments in the function body when they’re called which holds all the parameters passed. It is also worth noting that variables defined in a parent function are accessible inside a nested function (closure):
function foo() {
var a = 'From parent function';
var innerFoo = function() {
console.log ( a );
}();
}
// outputs: From parent function
foo();
On the other hand, the parent function, has no way to access local variables from the inner function:
function foo() {
var a = 'From parent function';
var innerFoo = function() {
var b = 'From inner function';
console.log ( a );
}();
console.log ( b );
}
// outputs: Uncaught ReferenceError: b is not defined
foo();
Memo
One of JavaScript difficulties resides in understanding how the this keyword behaves. If you have been developing with ActionScript, the this keyword behaves like with ActionScript 1 and 2. You may think that this will always point to the original context the function has been defined on, it actually points to the context of execution:
function foo() {
console.log ( this );
}
// outputs: Window {top: Window, window: Window, location: Location, external: Object, chrome: Object…}
foo();
By default, the global scope is the Window object, the core document class of the browser. In this example, the function becomes a method of the Window object:
// outputs: Window {top: Window, window: Window, location: Location, external: Object, chrome: Object…}
window.foo();
In this example, two variables x and y are defined on the global scope, therefore properties of the Window object:
// some position
var x = 200;
var y = 300;
function foo() {
console.log ( this.x, this.y, x, y );
}
// outputs: 200 300 200 300
foo();
In this case, this points to the global context (Window), where our properties are defined. By omitting this, we implicitly target the global scope and can also access the x and y properties. At runtime, the VM will look for variables defined in the local scope of the foo function, if not available, it will look for them in the parent context. If local variables are defined inside the function, these will be chosen first. Therefore, the this keyword allows us to resolve ambiguity and always target the current context of execution, not the local scope:
// some position
var x = 200;
var y = 300;
function foo() {
// local variables
var x = 500;
var y = 500;
console.log ( this.x, this.y, x, y );
}
// outputs: 200 300 500 500
foo();
Remember at all times that the context of execution may vary. In the code below, even though the foo function is defined on the Window object, passing its reference exports it to the context of myObject:
// some position
var x = 200;
var y = 300;
function foo() {
console.log ( this.x, this.y, x, y );
}
var myObject = { x : 400, y : 400 };
// pass a reference to the foo function
myObject.foo = foo;
// outputs: 400 400 200 300
myObject.foo();
Now this, points to the current object the function is executed on. We can also decide on which context is going to be used using the call API available on any function. In the following code, we execute our foo function back on the Window scope:
// some position
var x = 200;
var y = 300;
function foo() {
console.log ( this.x, this.y, x, y );
}
var myObject = { x : 400, y : 400 };
// pass a reference to the foo function
myObject.foo = foo;
// outputs: 200 300 200 300
myObject.foo.call ( this );
We can also new a function using its name and treat it like a function constructor:
function Point(x, y) {
this.x = x;
this.y = y;
}
var p = new Point(30, 30);
// outputs: Point {x: 30, y: 30}
console.log ( p );
// outputs: 30, 30
console.log ( p.x, p.y );
In this scenario, this allows us to reference the current context of the object that we instantiated and define its properties. If we do not use this, we declare x and y as global variables (or local if preceded with var) and fail to define the object properties:
function Point(x, y) {
x = x;
y = y;
}
var p = new Point(30, 30);
// outputs: Point {}
console.log ( p );
// outputs: undefined undefined
console.log ( p.x, p.y );
We can use the this keyword to reference the current scope to define our new distance method through a distance property:
function Point(x, y) {
this.x = x;
this.y = y;
this.distance = function (point) {
var dx = Math.abs ( this.x - point.x );
var dy = Math.abs ( this.y - point.y );
return Math.sqrt (dx*dx+dy*dy);
}
}
var p1 = new Point(30, 30);
var p2 = new Point(50, 90);
// outputs: 63.245553203367585
console.log ( p1.distance( p2 ) );
To augment the capabilities of a custom or native object, and perform subclassing, we would have to rely on the prototype object.
Memo
سرانجام بعد از دو سال شایعه، در ساعات آخر دیروز (به وقت ما) ساعت اپل معرفی شد. به عنوان اولین نکته ما دریافتیم که نباید به ساعت اپل، آیواچ بگوییم و باید همان ساعت اپل خطاباش کنیم.
همان طور که در پخش زنده دیشب متوجه شدید، این گجت به خاطر تازگی، ما را با انبوهی از سؤالات و حاشیهها مواجه میکند. به همین خاطر در این پست، نکاتی که در معرفی شتابآلود ساعت در پخش زنده همایش فرصت نشد در مورد آن توضیح دهم، هماره عکسهای فراوان مطرح میکنم.
ساعت اپل سنورهایی برای پایش فعالیت بدنی دارد و میتواند با یک آیفون جفت شود.
ساعت اپل دو اندازه ۱٫۵ و ۱٫۶۵ اینچی دارد و رنگها و مدلهای مختلفی دارد.




اپل امیدوار است با این ساعت مبدل به نخستین شرکتی شود که یک ساعت هوشمند موفق را روانه بازار میکند، چیزی که گمان نمیرود موتو ۳۶۰ هم موفق به آن شود.
پنل سافایر این ساعت به ملایمت انحنا پیدا میکند و بدنه اصلی ملحث میشود. پیچ تنظیم روی ساعت، برخلاف ساعتهای معمول، هنگام چرخش کلیک یا فیدبک فیزیکی نمیدهد و به همین خاطر مدتی طول میکشد تا کاربر به آن عادت کند.
قضاوت شخصی من این است که علیرغم همه برتریها و ابتکارهایی که در طراحی مدلهای مختلف ساعت اپل به چشم میخورد، باز هم این ساعت از حیث زیبایی قابل رقابت با ساعتهای کلاسیک نیست. اما در روزگار دیجیتال با توجه به کاراییهای فراوان ساعت، انتظار میرود با آشنایی تدریجی مردم با آن، این ساعت بتواند سهمی از بازار ساعتها را از آن خود کند.
این دو عکس را ببینید، به نظرتان ساعت اپل بدون در نظر گرفتن عملکردهیا فوقالعاده آن، جلوهای به اندازه یک ساعت کلاسیک سوئیسی دارد؟! البته شاید ساعت طلایی یا واچ ادیشن، ظاهری بهتر داشته باشد. اما معلوم نیست، چقدر باید بابت آن بپردازیم!


به گمان من گرچه طراحی بدنه ساعت نسبت به ساعتهای دیگر بهتر است، اما چیزی که باعث برتری ساعت اپل میشود، رابط کاربری آن، کیفیتهای اپهای در دسترس آن و همچنین توسعهدهندگانی است که خود را وقف ایجاد کاراییهای جدید برای آن میکنند.
شما تصور کنید که همین قابلیت ارسال ضربان قلب یا رسم اشکال روی ساعت، چه کاراهایی که پیدا نمیکند و چه ایدههایی نبوغآمیزی بر اساس آنها در قالب اپها پیاده نخواهد شد.
عمده نگرانی ما در مورد میزان شارژ باتری است، به نظر میرسد که اگر اپل، تمهیدی برای مشکل شارژ اندیشیده بود، خیلی روی آن مانور میکرد. پس تصور ما این است که مثل بقیه ساعتهای با صفحه لمسی رنگی مثل موتو ۳۶۰ یا ال جی جی واچ یا ساعتهای Gear سامسونگ، میزان شارژ باتری هم در حد حداکثر یک روز باشد. و به گمانم اپل درست به همین خاطر شارژر وایرلس القایی را برای ساعت، تولید کرده است تا با این کار، شارژ روزانه ساعت را سادهتر کند!

البته تیم کوک در جایی عامدانه یا تصادفی به شارژ محدود ساعت اشاره کرد، وقتی که گفت «وقتی ساعت را شب شارژ کردید.» این گفته میرساند که شارژ هر شبه ساعت، چیز مورد انتظاری است!
ساعت اپل که تیم کوک، آن را فصل تازهای در تاریخ اپل میداند، اما واقعا از یک نظر میتواند وسیلهای واقعا انقلابی باشد: این ساعت یک ابزار پایشکننده سلامت و فعالیتبدنی بینظیر است.
ممکن است بگویید ما پیش از این حسگرها و ابزارهای زیادی برای این کار میشناختیم، اما باید بگویم که ترکیب حسگرهای این ساعت با پلتفرم اپل، اپلیکیشنهای با رابط کاربری عالی و ویبره خاص ساعت، ترکیب واقعا محشری است.
تصور کنید که من پشت کامپیوتر نشسته باشم و در حال تنظیم یه مقاله طولانی مثل این باشم، و ساعت اپل را به دست کرده باشم، ناگهان ساعتم ویبره بخورد و به من اخطار داده شود که ۲۰ دقیقه تمام کاملا ساکن بودهام، برخیزم و کمی به خود تکان بدهم و بعد کار را از سربگیرم.
اپ اکتیویتی یا فعالیت برای نشان دادن میزان فعالیت کلی کاربر، از سه حلقه استفاده میکند:
حلقه جنبش، حلقه ورزش و حلقه ایستادن.

حلقه جنبش: هر هفته میزان معینی کالریسوزی برای خودتان تعریف کنید و ببینید چقدر به این هدف نزدیک شدهاید. هر گاه حلقه کامل شود، شما موفق شدهاید.
حلقه ورزش میزان ورزش شما را نشان میدهد، هر فعالیتی در سطح پیادهروی و بالاتر ورزش محسوب میشود. اگر هر روز ۳۰ دقیقه یا بیشتر ورزش کنید، حلقه کامل میشود.
و حلقه ایستادن نشان میدهد که در طول روز چه مقدار میایستید. مسلما ایستادن بهتر از نشستن است!
حالا تصور کنید، همه اینها را بتوانید روی یک دستگاه آیفون مرور کنید و ببینید در طول یک ماه چه مقدار حلقه کامل کردهاید!

اپ Workout به صورت زنده نشان میدهد که مدت ورزش شما چقدر بوده، چقدر کالری سوزانیدهاید،چه مسافتی را طی کردهاید و سرعت شما چقدر بوده است.

به علاوه ساعت برای خودش تایمر، شمارشگر معکوس و نیز سیستم هشدار سکون دارد.
نوشتن در مورد رابط کاربری ساعت اپل به صورت متنی، دشوار است، اما اگر توفیق دیدن ویدئوی این ساعت را داشته باشید، میتوانید تصدیق کنید که چقدر اپل خوب از پس این کار برآمده است و توانسته است یک رابط کاربری عالی برای یک صفحه نمایش ۱٫۶۵ اینچی تعریف کند.
اپل در پاسخ به سلایق مختلف، شش نوع بند ساعت مختلف با رنگ و جنسهای مختلف معرفی کرده است که میتوانند به سادگی به بدنه اصلی ساعت، متصل شوند.
از نظر تکنیکی قابل حدس است که مهندسان اپل، دشوارهای متنوع فنی برای گنجاندن این همه تراشه و حسگر مثل حسگر ضربان قالب، شتابسنج، ژیروسکوپ، موتور Taptic داشتهاند و توانستهاند همه آنها را حل کنند. مراجعه به سایت اپل نشان میدهد که اپل همه چیز را در یک تراشه واحد خلاصه کرده و در ساعت جای داده است.

صفحه نمایش این ساعت، از حیث دیگری هم متفاوت است، این صفحه نمایش می تواند تفاوت بین لمس ساده و لمس با فشار را درک کند و به این ترتیب کاربر میتواند با لمس با فشار، تعاملات جدیدی با این گجت داشته باشد و یک نوع راست کلیک را اعمال کند.
چیز جالب دیگری که در بالا هم به آن اشاره کردم و مایلم بیشتر در مورد آن صحبت کنم این است که اپل در قالب این ساعت، نوع تازهای از تعامل بین کاربران را معرفی کرده است، نوعی از تعامل و ارتباط که نیاز به مبادله متنی صدا یا تصویر ندارد و نامش digital touch است.
بله، شاید بگویید که ما در اپهای پیامرسان هم میتوانستیم اشکالی با انگشت خود لمس کنیم و برای دوستان خود بفرستیم، اما همین نوع ارتباط در ترکیب با ساعت، عملا چیز محشری میشود. خیلی وقتها ما حرفی برای فرستادن به دوست خود نداریم یا میخواهیم مینیمال سخن بگوییم، در این صورت چه چیز بهتر از فرستادن یک شکل منیمیال؟ به علاوه شما میتوانید با اموجیها هم با دوستان خود ارتباط برقرار کنید. حدس من این است که سال آینده در همین موقع، این نوع ارتباط بسیار مرسوم و محبوب شود!

و البته شما میتوانید به ملایمت روی گوشی تپ کنید تا به دلدار خود بفهمانید به فکرش هستید یا اینکه ضربان قلب خود را برایش بفرستید!!

از ساعت اپل میشود برای کنترل پخش موسیقی از آیفون، کنترل اپل تی وی و نیز به عنوان منظرهیاب آیفون استفاده کرد.
در اینجا پوستههای ساعت متنوع ساعت اپل را مرور میکنیم:

قیمت ساعت کمی مایه نگرانی است و از آنجا که قیمت ابتدایی آن ۳۴۹ دلار است، به نظر نمیرسد به همین سادگیها توسط شمار زیادی از مردم خریداری شود. به نظرتان قیمت مدل طلای ۱۸ عیار آن چقدر خواهد بود و اصولا کسانی که به دنبال مدلهای تجملی هستند و زیاد به کارایی ساعت فکر نمیکنند، حاضرند به جای ساعتهای لوکس، ساعت اپل طلایی بخرند؟
یک بار دیگر ۳ مدل ساعت را با هم مرور میکنیم:
اپل واچ: که بیشتر برای کسانی به نظر میرسد که در خانه و محل کار میخواهند از آن استفاده کنند. جنس بدنه آن از فلز ضدزنگ است.




مدل واچ اسپورت مناسب کسانی است که میخواهند با ساعت ورزش کنند. بدنه این ساعت از آلومینیوم است و بند آن پلاستیکی و بادوام است.


مدل شیک واچ ادیشن بدنهای از طلای ۱۸ عیار دارد.


فید یک پزشک محل مناسبی برای تبلیغات شما: محل تبلیغات متنی و بنری شما
این روزها، روزها خوبی برای طرفداران اپل نیست و در همان ابتدای این مقاله باید بگویم که برخلاف چیزی که شاید برخی از شماها تصور نویسنده این سطور هیچ قراردادی برای حمایت همیشگی و «فن» بودن اپل نبسته است و میخواهم از این پست استفاده کنم و از اپل و جانی آیو و مدیریت تیم کوک، انتقادهایی کنم.
مشکل وبلاگنویسهای فناوری در ایران
وبلاگنویسهای ایرانی، از لحاظ بازتاب اخبار فناوری، مشکل خاصی ندارند. شاید دو سه سالی بشود که آنها سرعت عمل بسیار خوبی پیدا کردهاند و از نظر ادبیات نگارشی هم موفقتر بودهاند و از نظر تکنیکهای مدیریت رسانهای خود را بسیار تقویت کردهاند.
مشکل عمده در این دو محور است:
۱- کمتر پیش میآید که شخصا در مورد یک سرویس اینترنتی یا یک گجت اظهار نظر شخصی بکنند، مقایسه کنند و پیشنهاد بدهند.
۲- کمتر پیش میآید که فناوریها و حواشی را در خدمت به انسان و در رابطه با ارتقای ذهن و کاراییهای ما تفسیر کنند، آیندهبین باشند و فارغ از نظر وبلاگهای معتبر انگلیسی، خود دست به نقد و آفرینش یک مقاله بزنند.
بله! ما وبلاگنویسیهای فناوری خیلی کم پیش میآید که شخصا به اخبار دست اول دست پیدا کنیم، بودجهمان خیلی محدود است، عوامل لازم را نداریم، مثلا نمیتوانیم وقتی به CES رفتیم، در یک گروه ۷-۸ نفری برویم و با تقسیم کار همه رویدادها را بازتاب دهیم و تفسیر کنیم. اما از همین جا با همین اینترنت حلزونی محدود هم هنوز گاهی میتوانیم کارهایی بکنیم و نظریهپردازی کنیم!
البته یکی از مشکلات پیش پای ما وبلاگنویسهای فناوری هراس از بازتابهای و تعاملات منفی برخی از کاربران ماست. همین امر باعث میشود که هنگام نقد پدیدهها، رویدادها و محصولات فناوری، ما همیشه محافظهکارانه عمل کنیم و دست به عصا راه برویم و در انتخاب کلمات و جملات خود احتیاط بیش از حد کنیم و به جای ارائه نظریات شخصیمان، سعی کنیم نظرات بلاگرهای دیگر را منعکس کنیم.
به عبارت دیگر ما واهمه داریم که در صورت اشتباه در ارزیابی با فرضا یک پست تکانهای به سختی تنبیه شویم و فرضا از ما سؤال شود که شما در مقام یک آدم غیرمتخصص در امور فناوری، چطور میآیید و از یک شرکت بزرگ با آن همه ذهنها خلاق و مهندسان باسابقه انتقاد می کنید!
با این همه وقتی این چند روزه مقالهای مناسبی پیدا نکردم که در آن تحلیل شده باشد که «چرا» ساعت اپل یا اصولا همه ساعتهای هوشمندی که تا به حال ساخته شدهاند، زیبا نشدهاند، تصمیم گرفتم خودم دست به کار شوم و مقالهای بنویسم.
وقتی شنیدیم که از جانی آیو روایت شده است که ساعت اپل، کار و کاسبی ساعتسازان سوئیسی را به مخاطره خواهد انداخت، بسیار خشنود شدیم. چون هیجان داشتیم این ساعت جدید را که قرار است هنر و زیبایی و یک محصول کارای فناوری پوشیدنی را با هم بیامیزد، ببینیم.
خوشحالی ما نه به خاطر موفقیت یک برند و شرکت، بلکه به خاطر معرفی یک رده محصول جدید بود. ما دوست داشتیم که همان تجربه آیپد تکرار شود، طوری که با ورود اپل به بازار، ناگهان «رده تبلت» پا گرفت و مطرح شد. ما دوست داشتیم که از این به بعد، در کنار، گوشیها و تبلتها، ساعتهای هوشمند را ببینیم. آن هم نه به عنوان اسباببازیهای عجیب، بلکه به عنوان ابزارهایی که زندگی ما را تغییر خواهند داد و راههای جدیدی برای ارتباط سریعتر و آنیتر و رفاه بیشتر ما فراهم آورند.
ساعت اپل با چه ذهنیتی میتوانست موفق باشد؟
به گمان من گروه طراحی اپل و جانی آیو، در حل مسئله غامض ساعتهای هوشمند موفق نبودند، گرچه بارقههایی از ابتکار در طرح آنها به چشم میخورد، اما آنها در آستانه دروازههای پیروزی متوقف شدند. ممکن است آنها در نسخه دوم ساعت خود، موفق شوند، فقط به شرطی که نگاهی نو به آنها تزریق شود.
اپل در دو صورت میتوانست یک ساعت هوشمند زیبا بسازد: ۱- المنتهایی زیباییشناسانه قبلی در ساعتهای مچی را یک به یک شناسایی کند و آنها را با کمی تغییر در قالبی دیجیتال بازآفرینی کند. ۲- خود، مفاهیم زیباییشناسانه جدید خلق کند.
اما واقعا کار دوم از عهده یک شرکت فناوری برنمیآید، بلکه در صلاحیت طراحان مد و زیبایی و متخصصان طراحان صنعتی شرکتهای بزرگی است که دهههای طولانی در این راه تلاش کردهاند. تازه، آنها هم به آرامی روندها و مدها و سلیقههای را تغییر میدهند و کمتر پیش میآید مثلا در طراحی لباس و کیف و کفش و زیورآلات، ناگهان یک مفهوم کاملا تازه بیافرینند.
پس:
مشکل شماره یک اپل، ارزیابی نادرست از زیباییشناسی ساعتهای کلاسیک و ندانستن ذائقه مردم بود. سالهاست که ساعتسازان معتبر از امگا و رولکس گرفته تا تیسوت و سیکو، طبق فرمول کلی امتحان پسدادهای ساعت مچی میسازند.
1- کاربران فقط به ساعتهای با صفحه دایرهای روی خوش نشان میدهند:
آیا ساعت کلاسیک موفق و زیبایی دیدهاید که صفحه دایرهای نداشته باشد. انسانها از نظر زیباییشناختی انحنا و سطوح گرد را به خطوط راست و زوایای تیز ترجیح میدهند. اپل نمیتواند این حس فطری زیباییشناختی را تغییر بدهد.
بله! مشکلات تکنیکی همیشه وجود دارند، اما مگر موتو ۳۶۰ همین مشکل را نداشت. آیا برای شرکت بزرگی مثل اپل، برطرف کردن این مشکل بعد از ۲ سال کار دشواری بود.
با این کار مسلما، فضاهای مفیدی به خاطر دایرهای شدن ساعت از دست میرفت، اما ما اصلا در یک ساعت به صورت پیشفرض با فضای محدود سر و کار داریم و باید سعیمان باشد همه چیز را در فضای محدود تعریف کنیم.
۲- باز یک ساعت کلاسیک را با دقت نگاه کنید. چه چیز دیگری ساعت مچی شما را زیبا کرده است؟
عقربههای مختلف، علایم روی صفحه، تکان خوردن عقربهها و جلوهها نور و سایه خفیفی که با تکان خوردن عقربهها ایجاد میشود.
مسلما در یک ساعت هوشمند، دیگر نیازی به اجازی مکانیکی و عقربهها نیست، بلکه باید با شیوههای مختلف این جلوهها را شبیهسازی کرد.
ساعت اپل گرچه جلوههای متنوعی برای بازسازی جلوه مکانیکی دارد، اما چندان موفق نبوده است. به فضای آزاردهندهای مشکی بین در گوشهها نگاه کنید. این فضا به خاطر دایرهای نبودن صفحه نمایش ایجاد شده است.

مشکل بعدی این است که طبق فلسفه جدید طراحی فلت که در ذهن جانی آیو دیگر نهادینه شده است، او دیگر علاقه برای بازسازی دیجیتال رویدادهای مکانیکی در محصولات اپل ندارد، اصطلاحا که اسکئومورفیسم را به کنار نهاده است.
اما اتفاقا بسیار خوب بود که در ساعت اپل، لااقل در بعضی جاها از اسکئومورفیسم استفاده میشد. برای مثال ترتیبی داده میشد که هنگام حرکت عقربهها، جلوههایی ظریف و دقیق از سایه در کنار و پشت عقربهها ایجاد میشد.
حتی میشد از جلوه پارالاکس هم استفاده کرد، طوری که وقتی کاربر ساعت را کمی تکان میدهد، صفحه ساعت کمی تغییر پیدا کند.
۳- اما واقعا با همین دو کار ساعت اپل موفق میشد، مسلما خیر!
فرض کنید که اپل چیزی شبیه موتو ۳۶۰ میساخت:

فرض کنید که اصلا ساعت اپل این طوری بود:

آیا ما ساعت زیبایی داشتیم؟
ابدا!
هنوز چیزهای کلیدی دیگری باقی ماندهاند.
برای این کار شما باز هم باید یک ساعت مچی شیک را در دست خودتان بگیرید و از خودتان بپرسید، واقعا چه چیزها و اجزایی این ساعت را زیبا و خواستنی کرده است؟
همان طور که در یک گوشی، کیفیت بدنه و نوع طراحی لبه، حاشیه و پشت گوشی برای ما مهم است، در یک ساعت هم مسلما این امر بسیار اهمیت دارد.
خب، به این ساعتهای تیسوت نگاه کنید:



بله! حاشیه صفحه نمایش، همان قسمتی که در گوشیهای موبایل اهمیت خاصی ندارند و اصطلاحا به آن bezel گفته میشود.

طبق روندی که هماکنون در گوشیهای هوشمند به جریان افتاده این bezel چیزی مزاحم است و حتی برخی برای عریض کردن صفحه نمایش، سعی میکنند آن را به کلی حذف کنند.
اما نه! این bezel اتفاقا چیزی است که اگر در یک ساعت هوشمند به آن اهمیت ندهید، کلی ضرر میکنید!
این قسمت حاشیه با یک شیب ملایم و جلوه فلزی که ایجاد میکند، ساعت را بسیار زیبا میکند.
شاید اپل به فکر ساخت این قسمت در طراحیهای اولیه بوده است، اما احتمالا خیلی زود طراحان با خود فکر کردهاند:
اوه! صفحه نمایش را که دایرهای کردیم و کلی از اندازه صفحه نمایش به همین خاطر کم شد، حالا به خاطر این bezel بیاییم و باز هم کلی فضای مفید دیگر را حرام کنیم؟!
اپل باید با این امر کنار میآمد که اصولا در یک ساعت هوشمند، این محدودیت اندازه صفحه نمایش وجود دارد و کل فرایند را را باید بر همین اساس انجام دهد، اپل باید ایمان میآورد که در همان دایره محدود با قطر ۳٫۵ سانتیمتر باید همه کارهایش را انجام بدهد.
حالا این سؤال پیش میآید که فرض کنید که این bezel را ساختیم و ساعت هم زیبا میشد، عملا به نظر این قسمت، یک قسمت مکانیکی بدون کارایی در یک ساعت «هوشمند» نمیشد؟ آخر چطور انتظار دارید که ما یک ساعت مدرن هوشمند داشته باشیم، و بعد بیاییم و اجزایی مکانیکی را در آن تعبیه کنیم که به هیچ کاری نیایند.
پاسخ در این است که اتفاقا اپل باید برای این بخش «عملکرد» هم ایجاد میکرد!
چطور؟
به باور من، رابط کاربری اپل برای ساعت هوشمندش، هوشمندیهای خوبی دارد. مشکل اصلی این بود که نمیشد با همان رابط کاربری گوشی و تبلت، با یک صفحه نمایش محدود ارتباط برقرار کرد. به همین خاطر اپل gestureهای جدید را معرفی کرد و یک پیچ یا اصطلاحا digital crown هم معرفی کرد که با آن میشود مثلا در یک نقشه زوم کرد و تا حدی نقش دکمه هوم را بازی میکند.
اما اپل فقط با کمی ابتکار بیشتر، میتوانست رابط کاربریاش را ارتقای بیشتری بدهد و یک رابط کاربری کاراتر معرفی کند و برای تعامل با گوشی از همین قسمت bezel استفاده کند.
برای این کار من موقع نوشتن این مطلب، ساعتم را برداشتم و با خودم تخیل کردم که این ساعت، ساعت هوشمند اپل است. انگشتهایم را روی قسمت حاشیه گذاشتم و با خودم فکر کردم که چه میشد، اگر برای این قسمت هم اعمال لمسی معرفی میشد؟

بله باز هم مشکلات تکنیکی ممکن بود وجود داشته باشند، اما باز هم برای مهندسان اپل آن هم در ۲ سال زمان کار روی این پروژه این چیز مشکلی نبود.
تصور کنید که اپل لمس یک انگشتی و دوانگشتی برای این قسمت معرفی میکرد:
- در هنگام لمس دوانگشتی، یعنی وقتی مثل همین تصویر بالا انگشت شست و اشاره خود را روی bezel گذاردهاید، میتوانید مثلا دو انگشت را به صورت دایرهای به سمت راست بگردانید، چیزی شبیه گرداندن فرمان خودرو به سمت راست.
متعاقب این عمل اپل میتوانست برای این gesture اعمالی تعریف کند، مثلا با این عمل میشد صفحات اپلکیشن را جلو عقب کرد یا توییتها و پیامکها را یک به یک دید.
حالا اپل میتوانست برای همین قسمت لمس یک انگشتی هم معرفی کند. کافی بود که کاربر انگشت خود را روی قسمت حاشیه بگذارد و کمی بالا و پایین ببرد یا تپ کند.
حالا ممکن است بگویید، وقتی که خود صفحه نمایش ساعت اپل لمسی است، چرا باید اعمال لمسی برای قسمت حاشیه هم تعریف کنیم؟
پاسخ این است که ساعت اپل کوچک است و وقتی شما انگشت روی آن مینهید، عملا فضای خیلی زیادی را دیگر نمیبینید. شما با یک تبلت یا گوشی که صفحه نمایش بزرگ دارند، طرف نیستید، مثل این میماند که شما هنگام کار با یک تبلت کف دست را رویش بگذارید!
به این ترتیب من معتقدم برای یک ساعت هوشمند، وجود یک قسمت bezel که به زیبایی طراحی شده باشد و عملکرد لمسی هم داشته باشد، ضروری است.
مشکلات تکنیکی را هم میشد با سادگی رفع کرد، اینها چیزهایی حاشیهای هستند.
۴- بعد از قسمت مغفول حاشیه میرسیم به قسمت پیچها:

پیچها واقعا یکی از قسمتهایی هستند که ساعتها مچی را زیبا میکنند، خوشبختانه اپل یک digital crown برای ساعت هوشمند خود معرفی کرده است که هم زیباست و هم کارا.

اما اگر قسمت bezel را با آن عملکردها به رسمیت بشناسیم، تعریف عملکرد برای این قسمت کمی دشوار بشود. اما به هر حال در هماهنگی با سیستم عامل و رابط کاربری میشود این قسمت را حفظ کرد و اعمالی هم برای آن تعریف کرد.
۵- قسمت دیگری که در همه ساعتهای مچی موفق وجود دارد و در ساعتهای هوشمند تا به حال به آنها توجه نشده است، چیست؟
این قسمت، قسمتی است که من نمیدانم اصطلاحا به آن چیز میگویند، اما من اسمش را یال میگذارم!


کلا از نظر زیباییشناسی همان طور که گفتیم انسانها به انحناها علاقه دارند. چرا خط نستعلیق زیباست، به خاطر همین انحناهای زیبا، به خاطر اینکه بعد از هر گردی و هر قسمت توپری، یک قسمت باریک داریم که به نرمی به هم تبدیل میشوند.

در طراحیها هم باید به این نکته توجه داشت.
اگر صفحهدایرهای ساعت هوشمند شما، ناگهان و بدون تأمل به یک بند ساعت بچسبد، گذر ناگهانی از صفحه ساعت هوشمند به بند ساعت که از هر نظر ممکن است متفاوت باشد، ترکیب زیبایی ایجاد نمیکند، شما ناگهان دو جزء را در کنار هم میبینید که از نظر جنس و بافت و بازتاب نور با هم متفاوتند.
اما این قسمت یال کمک میکند که صفحه نمایش به نرمی به بند ساعت بچسبد.
این قسمت با تراشها و سطوح مختلف و بازتابهای فلزی نور، میتواند یک ساعت را بسیار زیبا کند.
نکته: حتی میشود برای این ۴ یال به زیرکی عملکرد سختافزاری معرفی کرد!
من به چیز فکر میکنم؟!
به ۴ باتری کوچک در درون این یالها که بتوانند ماندگاری شارژ باتری را از یک روز به ۲ روز افزایش دهند! در طراحی عادی، شما باید یک ساعت دایرهای داشته باشید که به بند ساعت بچسبند. اندازه خود ساعت را که نمیتوانید زیاد بزرگ بگیرید، ضخامتاش را هم همین طور. اما این قسمت یالها در حکم افزونهای هستند که هم ساعت را زیبا میکنند و هم میشود از آن استفادههایی کرد.
بله مشکلات طراحی صنعتی قالب پیشبینی هستند. قابل پیشبینی است که مداری که بخواهد جریان را به این ۴ قسمت انتقال بدهد، پیچیدگی خاص خود را خواهد داشت. اما برای اپل با آن همه سرمایه و آن همه مهندس، باز هم این کار دشواری نیست.
۶- مشکل بعدی ساعت اپل این بود که قسمت اصلی ساعت، دارای نسخههای مردانه و زنانه نبود.
چطور میتوانید قدم به دنیای مُد بگذارید و از رقابت با ساعتسازان سوئیسی حرف بزنید، وقتی ساعت شما نسخه مردانه و زنانه ندارد؟!
آیا از بندهای ساعت اپل میتوانم خُرده بگیرم؟ نه چندان! اپل دستکم در این قسمت خیلی خوب عمل کرده است، اما مسلما اگر قرار بود، طرح بالا پیاده شود، بندهای ساعتاش را باید نوع دیگری طراحی میکرد.
دست آخر اینکه به نظر میرسد ذهنیت طراحی جانی آیو و گروهش، آنچنان که تصور میکردیم خلاق نیست و برخلاف آن ویدئوی زیبایی که در آغاز همایش اپل دیدیم، «نگاه متفاوت» و لااقل نگاه هوشمندانهای که بتواند قادر به تقلید و بازآفرینی زیباییهای کلاسیک در یک محصول دیجیتال باشد، فعلا از کاپرتینو رخت برسته است.
اپل ممکن است با گرفتن بازخورد، سال بعد، هم ساعت هوشمندش را اصلاح کند و هم زشتیهای آیفون ۶ در قسمت پشت را بزداید، اما فرق است بین شرکتی که که سابق بر این میتوانست، حتی پیش از خود مردم متوجه سلیقهها و نیازهای نهانی شود و شرکتی که حالا دست به آزمون و خطا میزند و «بازار» برایش تکلیف تعیین میکند.
با وجود همه این انتقادها معتقدم که ساعت اپل بعد از ورود به بازار به خاطر رابط کاربری و عملکردهایش و اپهایی که توسعهدهندگان برای آن خواهند ساخت، موفقترین ساعت هوشمند بازار خواهد شد، اما مسلما فاصله زیادی برای تبدیل شدن به یک «پدیده» خواهد داشت.
فید یک پزشک محل مناسبی برای تبلیغات شما: محل تبلیغات متنی و بنری شما
دسامبر سال پیش «اسپن هاگنسن» تصمیم گرفت که برای سفر و اسکی به Demmevass برود، بعد از پنج- شش ساعت او و گروهش به کلبه زیبایی در ارتفاعات رسیدند.

آقای هاگنسن، علاقه زیادی به عکاسی از ستارگان و کهکشان راه شیری دارد، اما در این سفر برای نخستین بار او لنز مناسب و سهپایه خوبی با خود برده بود. بدشانسی او این بود که ماه کامل در آسمان بود، اما در نیمه شب ماه ناپدید شد و او توانست عکس بسیار زیبایی بگیرد و در اکانت سایت ۵۰۰px خود آپلود کند.

این عکس به سرعت محبوب شد، اما شگفتی بزرگ وقتی رخ داد که اپل با هاگنسن تماس گرفت و عکس را خرید. ابتدا اپل عکس را بدون مجوز انتشار خریده بود، اما بعدا در ماه جولای مجوز انتشار عکس را هم خرید.
با این همه هاگنسن نمیدانست کی و کجا این عکس توسط اپل استفاده خواهد شد.
سهشنبه هفته پیش، زمان غافلگیری هاگنسن فرارسید، چون مطلع شد که اپل از عکس به عنوان بکگراند آیفون ۶ استفاده کرد.

البته در این عکس، تصویر کلبه از عکس برداشته شده است.

حالا آقای هاگنسن بسیار مشهور شده است، ما نمیدانیم که او چقدر بابت این عکس دریافت کرده است، اما عکس به زودی به عنوان یکی از عکسهای پیشفرض بکگراند آیفون ۶ خواهد بود.
توصیه میکنم بقیه عکسهای زیبای هاگنسن را هم ببینید.
فید یک پزشک محل مناسبی برای تبلیغات شما: محل تبلیغات متنی و بنری شما
بالاخره انتظارها به پایان رسید و اپل پرده از آیفونهای جدیدش برداشت. اپل امروز در کنفرانس اختصاصی خود 2 آیفون جدید معرفی کرد و بسیاری از قوانین نانوشته خودش را زیر پا گذاشت و هنجار شکنی کرد! با ما همراه باشید تا آیفونهای جدید را بهتر به شما بشناسانیم.
صفحه نمایش آیفون 4.7 اینچی که اینبار Retina HD نام گرفته است به رزولوشن عجیب و غریب 1334 در 750 پیکسل مجهز گردیده است. البته تنها توجیه ما برای این تغییر، اینست که اپل میخواسته کاربران دست و نویسندگان دست به قلم شده و با خواندن مقالههای گوناگون (میتوانید برای یافتن روش محاسبه چگالی پیکسلی به مقاله “مقایسهای متفاوت بین صفحهنمایش Quad HDبا Full HDو HD” مراجعه نمایید) چگالی پیکسلی جدیدی را محاسبه نمایند! نتیجه این محاسبات هم تراکم 326 پیکسل بر هر اینچ را نتیجه میدهد. آیفون پلاس هم به صفحه نمایش 5.5 اینچی با رزولوشن طبیعی Full HD طراحی شده و به دست کاربران میرسد. شایان گفت است که تراکم پیکسلی بچه غول دوست داشتنی اپل، 400 پیکسل در هر اینچ است. در نهایت اپل اعلام کرده که توسعه دهندگان با ارتقای برنامههایشان میتوانند به راحتی محصولاتشان را با رزولوشن تصویر جدید هماهنگ کنند.
لنز 8 مگاپیکسلی iSight، از دیگر موارد ارتقا یافته در آیفونهای جدید است. این لنز به کمک سختافزار گوشی، توانایی فیلمبرداری 1080P در حالت 60 فریم بر ثانیه را فراهم میآورد. البته حالتهای 120 فریم بر ثانیه و 240 فریم بر ثانیه هم قابل دسترس هستند اما باید رزولوشن تصویر را قربانی کنید و به حالتهای کمتر کاهش دهید.
سیستم روی یک چیپست بهکار رفته در آیفونهای جدید که A8 نام دارد، با تکنولوژی 20 نانومتری و با پشتیبانی از فناوری 64 بیتی ساخته شده است و مطابق ادعای اپل، پردازنده آن 20 درصد از نمونه قبلی و چیپ گرافیکی آن 50 درصد از نمونه قبلی قویتر است. لیتوگرافی 20 نانومتری منجر به کوچکتر شدن این چیپ متجمع گشته، بهطوریکه A8 تا 13 درصد کوچکتر از A7 طراحی شده است.
آیفون 6 پلاس در حافظههای 16، 64 و 128 گیگابایتی و به ترتیب با قیمتهای 299، 399 و 499 دلار تحت قرارداد اپراتورها در دسترس کاربران قرار میگیرد.


در کنفرانس امشب که به معرفی آیفون ها و ساعت هوشمند جدید اپل Apple Watch اختصاص داشت، اپل در کنار معرفی این محصولات و امکانات ساعتش، از قیمت پایه و زمان عرضه این ساعت نیز پرده برداشت.
بنا به اعلام تیم کوک، ساعت هوشمند اپل که در دو نسخه معرفی شد، از قیمت ۳۵۰ دلار عرضه خواهد شد.
این ساعت ها از اوایل سال آینده میلادی روانه بازار می شوند.
ساعت اپل برای کار با آیفون ۶، آیفون ۶ پلاس، آیفون ۵ اس، آیفون ۵ سی و آیفون ۵ سازگار است و برای استفاده از آن به یکی از آیفون های اشاره شده نیاز دارید.

دستکم ۱۵۰ هنرمند خیابانی از ۳۰ کشور دنیا به جزیره Djerba تونس آمدند تا روستای Erriadh را به بوم بزرگی نقاشی تبدیل کنند و آن را تبدیل به موزه روباز خود کنند.
مرور این عکسهای خالی از لطف نیست:












فید یک پزشک محل مناسبی برای تبلیغات شما: محل تبلیغات متنی و بنری شما
پایگاه خبری فناوری اطلاعات برسام
پایگاه خبری فناوری اطلاعات برسام -
درست خواندهاید، در حالی که شش روز به معرفی رسمی پرچمدار بعدی اپل یعنی آیفون ۶ باقی مانده است، افراد زیادی جلو درب اپل استور ها چادر زده اند و منتظر هستند این نسل از آیفون معرفی و روانه بازار شود.
به گزارش پایگاه خبری فناوری اطلاعات برسام و به نقل از انجمن تخصص آیفون، در حالی که هنوز مشخص نشده است چه مدت پس از معرفی آیفون ۶ امکان خرید آن فراهم میشود، اما این امر چیزی از شوق و اشتیاق این افراد کم نمیکند. گرچه شایعاتی نیز منتشر شده است که ممکن است مدل ۴.۷ اینچی آیفون ۶ در تاریخ ۱۹ سپتامبر روانه بازار شود و مدل ۵.۵ اینچی آن نیز مدتی بعد عرضه شود. البته به نظر میرسد این افراد هر سال این کار را انجام میدهند بنابراین نباید تحمل این چند روز برایشان بسیار دشوار باشد.
تصاویری که در ادامه مشاهده میکنید مربوط به یکی از زیباترین اپل استور های جهان یعنی اپل استور خیابان پنجم نیویورک میباشد.
سارقان برای دزدیدن پسورد کارتهای اعتباری، مجهز به ابزار جدید شدهاند، این ابزار جدید، فناوری فروسرخ است!
در روش جدید سارقان گوشی خود را مجهز به یک حسگر فروسرخ میکنند و بعد پشت سر قربانی میگیرند و بلافاصله بعد از اینکه او کسی پسوردها را وارد کرد، عکسی از صفحه کلید میگیرند. طبعا دکمههایی که اخیرا استفاده شده باشند، گرمتر هستند و در عکس مشخص هستند. بر اساس میزان گرمی، میتوان ترتیب فشرده شدن دکمهها را حدس زد.
شاید فکر کنید که دسترسی به یک دوربین فروسرخ دشوار باشد، اما باید بگویم که این روزها مثلا برای آیفون کیسهایی مثل کیس FLIR ONE با قیمت ۳۵۰ دلار عرضه شده است که مجهز به دوربین فروسرخ هستند!

مطابق یک بررسی جدید، اگر عکس بلافاصله پس از وارد کردن پسورد گرفته شده باشد، در ۸۰ درصد موارد میتوان پسورد را به درستی به چنگ آورد و اگر یک دقیقه گذشته باشد، شانس به دست آوردن پسورد پنجاه – پنجاه است.

میشود حدس زد که این روش چندان هم کارا نباشد و راههایی هم برای مقابله با آن باشد:
- سارق تا کارت شما را نداشته باشد، با پسورد تنها نمیتواند کاری بکند. اما خب، در نظر بگیرید که سارقی شما را تحتنظر داشته باشد و بخواهد در یک فرصت مناسب، کارت شما را برباید.
- دکمههای فلزی، چون نور فروسرخ اطراف را بازتاب میدهند، انجام این ترفند را دشوار میکنند.
- شما میتوانید با قرار دادن انگشت به صورت تصادفی روی دکمههای دیگر، از اجرایی شدن این ترفند جلوگیری کنید.
- یک محدودیت دیگر این ترفند این است که مشتریهای خودپردازها بعد از وارد کردن پسورد، در موارد زیادی، مبلغ مورد نیاز خود را هم وارد میکنند و این کار باعث اختلال در انجام این ترفند میشود.
طبعا در ایران با توجه با فرهنگها و رفتارهای عجیبی که رایج است، شاید نیازی به دوربین فروسرخ نباشد، وقتی که کاربران پشت سر شما، عملا آنقدر نزدیک قرار میگیرند که همه جزئیات کار شما را میبینند و یا وقتی که صاحبان فروشگاهها، به جای دادن اینکه اجازه بدهند مشتری خودش کارت را وارد پایانه کند و پسورد را وارد کند، پسورد را از مشتری میپرسند، ما باید به تهدیدهای امنیتی پیش پا افتادهتری فکر کنیم!
فید یک پزشک محل مناسبی برای تبلیغات شما: محل تبلیغات متنی و بنری شما
میتوان در مورد اثرات مضر سیگار مطالب زیادی نوشت، اما شاید دیدن یک ویدئوی کوتاه، بتواند بهتر شما را متقاعد کند.

این ویدئوی کوتاه را از اینجا با حجم ۷۶۰ کیلوبایت دانلود کنید.
اما اگر بخواهم توضیح کوتاه نوشتار بدهم باید بگویم که سیگار با کاهش سیستم طبیعی تمیزکاری ریهها و فلج کردن مژکها یا ciliaها، باعث تجمع آلودگیها و مواد ایجادکننده سرطان در ریه میشود.
سیگار احتمال ابتلا به سرطان ریه را افزایش میدهد.
سیگار عامل اصلی ایجاد بیماری COPD یا بیماری انسدادی مزمن ریه است.
سیگار باعث میشود که حبابچهها یا آلوئلهای ریه تخریب شوند و سطحی که در آن تبادل اکسیژن بین ریه و خون صورت میگیرد، به شدت نقصان پیدا کند.
فید یک پزشک محل مناسبی برای تبلیغات شما: محل تبلیغات متنی و بنری شما
چندی پیش در یکی از جلسههای بازاریابی، مشتری (بالقوه) از ما خواست که نرمافزار جامع مدیریت اطلاعات و آمار بهساد را به صورت آزمایشی در اختیار او قرار دهیم. تا اینجای کار منطقی بود. مشتری حق دارد پیش از آنکه بخواهد محصولی را خریداری نماید، آن را ارزیابی کرده و سپس در مورد خرید و یا عدم خرید تصمیم بگیرد. بهساد در این زمینه حتی پشتیبانی نرمافزار آزمایشی را ارائه مینماید. با اینحال وقتی که گفتیم ارائه نرمافزار آزمایشی با استفاده از سرورهای اینترنتی بهساد صورت میگیرد، آن را نپذیرفتند و اصرار داشتند که نرمافزار بر روی سرورهای آنها نصب شود. توجیه آنها هم این بود که در آینده میخواهند نرمافزار را در همین شرایط مورد بهرهبرداری قرار دهند و باید مشکلات احتمالی را هم در همین شرایط بررسی کنند.
از آنجا که رویه جاری بهساد با این کار متفاوت بود، موضوع در جلسه هماهنگی شرکت مطرح شد. برخی از دوستان مخالف بودند و برخی (از جمله من) موافق. دوستان مخالف مباحث امنیتی را طرح میکردند و من استدلالم این بود که در بازار نمیتوان با بدبینی تمام، فروش را پیش برد. به هر ترتیب به کارفرما اعلام کردیم که زیر ساخت لازم را در اختیار ما قرار دهد. چندین ماه گذشت تا سرانجام شرایط نصب آزمایشی فراهم شد و موضوع به صورت اولویت بالا در دستور کار شرکت قرار گرفت.
در هنگام نصب از راهدور، دوستی که مشغول انجام کار بود، من را صدا زد تا موضوعی را در سرور مشتری به من نشان دهد. موضوع شوکه کننده و تاسف بار بود! یک نرمافزار جاسوسی نصب کرده بودند که کلمههای عبور نصب برنامه و کلیه عملیات کپی فایل را ذخیره کند و از طرف دیگر هر ۱۰ ثانیه از فرآیند نصب برنامه عکس بگیرد! این که ما چطور متوجه این موضوع شدیم بماند. عکسها و فایلهای جاسوسی را پاک کردیم و در یک فایل Notepad برایشان نوشتیم که این کار (جاسوسی) پذیرفته شده نیست. به یقین هم Key Logger آنها آن را ثبت کرده و هم عکس صفحه گرفته شده و آن را دیدهاند.
من صلاحیت بحث در مورد اخلاقی بودن و یا نبودن این کار را ندارم. اما از نظر کسب و کار، آنها ضربه بزرگی به فضای عمومی کسب و کار کشور وارد کردهاند. از این به بعد در هیچ جلسهای من در چنین موقعیتی نمیتوانم از قابل اعتماد بودن یک شرکت دولتی بزرگ دفاع کنم. تمام دوستانی که از این اتفاق خبر دار شده و یا میشوند نیز، به هیچ کارفرمای دیگری در این زمینه به سادگی اعتماد نخواهند کرد. شرکتها هزینههای بیشتری خواهند کرد که محصولات آزمایشی (تحت وب) را بر روی سرورهای اختصاصی و مطمئن خودشان نصب کنند. این که ما به کارفرمایان اعتماد نداشته باشیم، به نوبه خود باعث گسترش فضای بیاعتمادی میشود و این باعث سلب اعتماد آنها از ما نیز خواهد شد. در این بازی هیچ طرف برنده نیست.
پایگاه خبری فناوری اطلاعات برسام
پایگاه خبری فناوری اطلاعات برسام -
یکی از مهمترین برنامههای سیستمعامل اندروید و دیگر سیستمعاملها مرورگر آنها میباشد. آمارها نشان میدهد بسیاری از کاربران به مرورگر اصلی اندروید خود اکتفا نمیکنند و مرورگرهای دیگری را مورد استفاده قرار میدهند.
به گزارش پایگاه خبری فناوری اطلاعات برسام و به نقل از گویا آی تی، برای سیستمعامل اندورید، مروگرهای مختلفی در فروشگاه ها قرار دارد و صادقانه باید بگویم که ممکن است در این که کدام را استفاده کنیم گیج شویم و به دنبال نامهای بزرگی همچون فایرفاکس و کروم برویم، اما آیا مرورگرهای دیگر نمیتوانند برای کاربران مفید باشند؟ در این قسمت یک مقایسهی همهجانبه بین بهترین مرورگرهای سیستم عامل اندروید در سال ۲۰۱۴ خواهیم داشت. پس با گویا آی تی همراه باشید.
توجه داشته باشید که تست مرورگر ها در اسمارتفون Oneplus One انجام گرفته است
طراحی و رابط کاربری مرورگرها در سالهای گذشته کمتر از بخشهای دیگر مورد توجه قرار گرفته است و مرورگرهایی که در موبایل استفاده میکنیم در واقع ورژن کوچک شدهی مروگرهای ویندوز با یک آدرس بار و منوی تبها میباشد. در حین تست متوجه شدیم که در میان تمامی مرورگرها فقط مرورگر Habit Browser نوار آدرس را در پایین صفحه قرار داده است و این کار دسترسی به آن را آسانتر کرده است، با توجه به اینکه این مروگر در لیست بهترینها نیست!
نمیگویم که این کار عالی است و همه باید آن را در مرورگرهای خود قرار دهند اما با اسمارتفونهایی که میانگین سایز آنها در حال عبور از مرز ۵ اینچ است، قرار گرفتن ادرس بار در بالا کمی مشکلساز است. اما بیایید به بررسی جداگانهی مروگر ها در زمینه طراحی بپردازیم.
اکثر کاربران سیستم عامل اندروید با این مرورگر آشنایی دارند، با توجه به اینکه اکثر شرکتها این مرورگر را به عنوان مرورگر پیشفرض و اصلی گوشی خود قرار میدهند. این مروگر در زمینه سرعت واقعا عملکرد خوبی دارد اما اگر بگوییم در زمینهی طراحی نیز مرورگر قدرتمندی است اشتباه کردهایم.
دستاورد شرکت گوگل در این مرورگر مانند دیگر پروژههایش واقعا قابل قبول است و برنامه باگ و مشکل خاصی ندارد. در هنگام تعویض تب، زوم کردن، بالا و پایین رفتن،تایپ کردن و دیگر موارد ، مرورگر کروم واقعا خوب عمل میکند.
همانند ورژن ویندوزی، نسخهی اندروید فایرفاکس نیز دارای یک طراحی ساده و زیباست و به نظر بسیاری از کاربران در زمینهی طراحی از کروم بهتر است. همچنین امکانات و گزینههای بیشتر و بهتری نیز در منوی فایرفاکس قرار گرفته اند. فایرفاکس همانند کروم در بسیاری از بخشها عملکرد روان و پرسرعتی دارد و به همین دلیل از جمله بهترینهای اندورید میباشد.
اپرا سومین مروگری است که در لیست ما قرار گرفته است. عملکرد این مروگر در بخش ویندوز اصلا تعریفی نداشته است و به نظرم اگر به همین نسخهی موبایلی خود اتکا کنند بهتر است البته نسخهی ویندوزی این مروگر نیز کاربران خاص خود را دارد. اپرا همیشه یک مروگر متوسط از هر لحاظ برای اندورید بوده است و هیچگاه ما را با ویژگیهای جدید سورپرایز نکرده است.
محیط کاربری این مرورگر چند ساله شده است و تغییر به خصوصی نکرده است و به نسبت مرورگرهای دیگر بسیارز ساده است. این سادگی برای بسیاری از کاربران یک ویژگی مورد پسند و خوب است. البته ساده بودن این مرورگر به معنای کمبود قدرت و سرعت در علکرد نیست بلکه در این بخش اپرا واقعا عالی است و قادر به باز کردن سنگینترین سایتها میباشد.
مرورگر دلفین سابقهی درخشانی در سیستم عامل اندروید دارد و سالهای زیادی است که در فروشگاهها قرار دارد و بر خلاف مرورگر اپرا در هر نسخه امکانات و ویژگیهای جدیدی را برای کاربران قرار میدهد. کاربران این مرورگر نیز بسیار به آن وفادارند و به سراغ مرورگر دیگری نمیروند. اما چرا؟
این مرورگر در زمینه طراحی با کروم و فایرفاکس رقابت نزدیکی دارد؛ انعطاف زیاد، گزینههای متفاوت و تمهای مختلف از جمله ویژگیهای این مرورگر محبوب است. همچنین تبهای سبز رنگ نیز جلوهای زیبا به این مرورگر دادهاند. امکانات این مرورگر آنقدر زیاد است که در قسمتی از مرورگر میتوانید با آنها آشنا شوید!
این مرورگر نیز با طراحی زیبایی که دارد، کاربران بسیاری را به خود جذب کرده است. یو سی در ایران نیز کاربران زیادی دارد. این مرورگر در زمینهی امکانات و طراحی به دلفین بسیار شباهت دارد. سرعت بالا در بارگذاری، یکی از ویژگیهای منحصر به فرد مرورگر UC است.
مرورگرهای CM Browser، Javelin، Next Browser و Lightning Browser نیز در لیست ۱۰ مروگر برتر سال ۲۰۱۴ قرار گرفته اند اما از بررسی جداگانهی آنها در زمینه طراحی صرف نظر میکنیم. البته عکسهایی را از منوی کاربری Lightning Browser و Javelin آنها در ادامه قرار دادهایم:
نمودار زیر امکانات و قابلیتهای تمام مروگر ها را بررسی میکند. به نظر شما کدام یک برایتان بهتر و کاربردیتر است؟
از لنزی که حس لامسه را به قرنیه می برد تا یک حلقه پرینت شده سه بعدی که متن را با صدای بلند (در زمان واقعی) می خواند، پیشرفت هایی در تکنولوژی راه های مبتکرانه ای را برای استفاده از محتوای چاپ شده در افرادی که مشکل بینایی دارند، باز کرده است.
محققانی از دانشگاه کرتین استرالیا، یک دستگاه خواننده ارزان قیمت معرفی کرده اند که اطلاعات گرافیکی را پردازش کرده و به نابینایان اجازه می دهد تا اسنادی مانند صورت حساب، فیل PDF و نامه های بانکی و گرافیکی را تحلیل کنند.
دکتر لین موری سخنرا ارشد دیپارتمان مهندسی برق و کامپیوتر دانشگاه کرتین؛ کسی که سیستم خواننده دیجیتال را با دانشوی PhD آزاده ناظمی توسعه داده است، در این باره می گوید: ” افراد نابینا اغلب از مسیر های شغلی خاص و فرصت های آموزشی که در آن نمودار یا گرافیک نقش اساسی ایفا می کند، باز می دارد. ما امیدواریم این دستگاه فرصت های جدیدی را برای افرادی که مشکل بینایی دارند، به وجود آورد.”
اندازه دستگاه 20x15x3 cm(7x6x1.1 in) می باشد که دارای مجموعه ای از کنترل های کنتراست بالا با نشانه گذاری های لمسی برای مسیریابی است. با استفاده از الگوی شناسایی، فناوری های یادگیری ماشین و طیفی از روش های تقسیم بندی ، سیستم مطالب را در بلوکی از متن و تصویر از یکدیگر جدا می کند که در جهت نظم صحیح خواندن مرتب شده اند.
سپس این بلوک ها را به عنوان تصویر، گراف، مطالب ریاضی یا متن شناخته شده و از تشخیص نوری کاراکتر (OCR) یا Mathspeak ، ابزاری برای قرائت محسبات ریاضی، بدست آمده است. سپس اطلاعات با نشانه گذاری ناویگیشن به فرمت صوتی تبدیل میشود و می تواند به 120 زبان مختلف از طریق موتور سخنگوی درونی ترجمه شود. دستورالعمل های صوتی نیز در درون دستگاه قرار داده شده است.
دکتر موری افزود: ” تمامی سنین با هر سطحی از توانایی به آسانی می توانند با سیستم ما کار کنند و ویگی متن باز بودن آن باعث می شود کسانی که مهارت لازم را دارند، با توجه به کاربردشان آن را تغییر دهند.” او انتظار دارد قیمت این دستگاه چیزی در حدود 100 دلار در هر واحد باشد؛ قیمتی که می تواند یک چاره واقعی برای بسیاری از افراد حتی در کشور های در حال توسعه باشد. او در حال حاضر به دنبال تامین مالی بشر دوستانه برای تولید دستگاه است.


نسل جدید، حتی آفتابه های شان هم فرق می کند. کجاست آن آفتابه های مسی؟ بگذریم، آفتابه ی دهه هفتادی ها از جنس apk است و نوع مصرفش هم متفاوت اما ساده تر. یک سری تصویر با المان های مختلف پیش روی شما قرار می گیرد و باید حدس بزنید که منظور از ترکیب این المان ها با یکدیگر چه بوده. برای مثال در تصویر بالا شخصی را می بینید که در حال پرتاب کردن دست است و این یعنی دست انداز.
گروه درخت، معتقد است نه تنها در هر خانه، بلکه روی هر گوشی اندرویدی هم یک آفتابه لازم است، به همین دلیل بازی به رایگان منتشر شده و منبع درآمد سازندگان جوان این بازی خوش ساخت، پرداخت های درون برنامه ای مربوط به سکه ها است. در واقع اگر در یکی از مراحل نتوانید به پرسش پاسخ دهید باید از سکه های تان استفاده کنید.
در حقیقت برای کسب سکه های بیشتر، یا باید جواب صحیح به سوالات دهید یا بخرید. سکه ها سخت به دست می آیند و بابت هر راهنمایی هم مقدار زیادی از شما گرفته می شود پس باید دقت کنید یا اینکه از راه دیگری وارد شوید.
همانطور که اشاره شد، آفتابه کاملا رایگان در اختیار مخاطبین کافه بازار قرار گرفته و تا به امروز هم مرز یک میلیون دانلود را گذرانده. نزدیک به ۱۸ هزار نفر بازی را دقیقا بررسی کرده و به آن امتیاز داده اند. میانگین کل امتیازات هم نشان می دهد که درصد اندکی از مخاطبین به این بازی امتیاز ۵ ستاره نداده اند.


حتما پیش آمده که خبرنامه هایی در اینباکس تان دریافت کنید که ندانید از کجا می آیند و یا بخواهید از دریافت آنها منصرف شوید؛ در این صورت ممکن است به دنبال کلید لغو اشتراک بگردید که معمولا در پایین خبرنامه های مذکور و بسیار ریز دیده می شود. اما جیمیل در آخرین به روز رسانی، این شرایط را تغییر داده است.
روز گذشته در صفحه اختصاصی جیمیل در گوگلپلاس طی پستی از چند امکان جدید خبر داده شد. مهمترین آن، جابجایی کلید Unsubscribe در بالای ایمیل و کنار نام ارسال کننده است.
این امکان در تمام ایمیل های دریافتی دیده نمی شود. در حالت عادی کلید لغو اشتراک در جایگاه قبلی اش قرار دارد اما گوگل این کار را بر اساس فیلترهای پیشفرضش اعمال میکند و ایمیل هایی که به صورت خودکار به تب های Promotions ،Social و Froums بروند، دستخوش این تغییر تازه نیز خواهند شد.
با این تغییر گوگل قصد دارد هر چه بیشتر به کاربران برای داشتن ایمیل های کمتر در صندوق پست الکترونیکی شان کمک کند. همچنین بدین ترتیب کمک می کند که مطالب تولیدی واقعی، کمتر در معرض اسپم اشتباه قرار گیرند.
در نقطه مقابل چنانچه شما بدون اشتراک یک خبرنامه از سایت یا تالاری ایمیل دریافت می کنید، به راحتی و بدون گشتن به دنبال کلید Unsubscribe می توانید از شر این اسپم های آزاردهنده خلاص شوید.


سرانجام روزی فرا می رسد که کاربران دیگر به طور صرف از تکنولوژی استفاده نمی کنند؛ در آینده ای نه چندان دور، تکنولوژی می تواند به بدن ما تزریق شود و همچون عضوی جدا ناشدنی در تمام اوقات همراهمان باشد.
این موضوع رؤیای نویسندگان رمان های تخیلی و البته افرادی است که خود را «آینده نگر» می دانند. ری کورزویل، یکی از آن افراد است که ترجیح می دهد از لفظ Singularity استفاده نماید. Singularity در واقع نقطه ای است که تکنولوژی و بدن انسان با یکدیگر ترکیب می شوند و به یکتایی می رسند. نقطه ای که انسان تکامل بعدی خود را تجربه می کند و تبدیل به موجودی متفاوت می شود.
سینگولاریتی همین حالا هم در جریان است. در این دنیای پهناور، هستند افراد شجاعی که تکنولوژی را در بدنشان تزریق کرده اند تا بدین گونه قادر باشند از پس کارهای بیشتری بر بیایند. در ادامه مطلب با دیجیاتو همراه باشید، تا با ۸ نفر از افرادی که به نوعی پیشرویان سینگولاریتی به حساب می آیند، بیشتر آشنا شویم.
نیل هاربیسون شاید معروف ترین سایبورگ (انسان خطاب کردن این افراد احتمالا کم لطفی در حقشان است) حال حاضر دنیا باشد. نیل به صورت مادرزادی از یک نوع نادر از بیماری کوری رنگ رنج می برد. بر خلاف بیماران عادی کور رنگی که تنها رنگی خاص را نمی توانند مشاهده کنند، نیل هیچ رنگی را نمی تواند تشخیص دهد.
او در سال ۲۰۰۴ دستگاهی را اختراع کرد که بعد ها به Eyeborg معروف شد. این دستگاه می تواند رنگ ها را به نوت های خاص موسیقی ترجمه نماید و سپس آن ها را به مغز نیل منتقل کند. بدین گونه نیل می تواند هر رنگ را با روش خاص خود تجربه نماید.
در سال ۲۰۱۰ هاربیسون انجمن سایبورک ها را افتتاح کرد تا بدین گونه بتواند به افرادی که دوست دارند تکنولوژی را در بدن خود به کار گیرند، کمک نماید.
آمال گرافسترا چیپ های مخصوص RFID را در دو دست خود تعبیه کرده است. در عکس بالا می توانید در میان انگشت شست و اشاره دستان آمال، این چیپ ها را مشاهده نمایید.
آمال بعد ها شرکتی به نام Dangerous Things افتتاح کرد و در آن به فروش کیت های مخصوص تعبیه تکنولوژی در بدن پرداخت. این کیت ها به نحوی طراحی گشته بودند که کاربران بدون نیاز به جراحی پیچیده، می توانستند خودشان نسبت به قرار دادن تکنولوژی در بدن، اقدام نمایند.
آمال از دست هایش برای کار های بسیاری بهره می برد. او چیپ ها RFID را به نحوی برنامه ریزی کرده است که درب خانه و خودرویش را باز کنند. او حتی دیگر نیازی به رمز گذاشتن بر روی کامپیوترش ندارد، چرا که با یک حرکت دست به راحتی خود را به کامپیوترش می شناسد.
چند سال پیش آدی روبرتسون آهن ربایی را در یکی از انگشتان خود تعبیه کرد و مدتی بعد نیز از شرکت Dangerous Things یک چیپ NFC خرید و آن را نیز در دستانش قرار داد.
آدی از آهن ربایش استفاده های بسیاری می کند، اما از چیپ NFC رضایت چندانی ندارد. او معتقد است که Near Field Communication هنوز تکنولوژی جدیدی به شمار می رود، و استفاده های زیادی برای آن طراحی نگشته است. آدی همچنین از اینکه آیفون از تکنولوژی موجود در دست هایش پشتیبانی به عمل نمی آورد، بسیار ناراحت است!
کوین وارویک، به عنوان یک پروفسور در دانشگاه Reading انگلستان مشغول به تحقیقات علمی است. او بیشتر بر روی حوزه هوش مصنوعی و رباتیک تمرکز دارد و تلاش می کند تا با ساختن بازویی مصنوعی به بیماران کمک نماید.
او در حین یکی از تحقیقات خود تصمیم گرفت تا دستگاهی را طراحی کند که به سیستم عصبی بدن متصل گردد و سپس اطلاعات لازم را در اختیار کامپیوتر قرار دهد. کوین هم اکنون این تکنولوژی را در بدن خود قرار داده و با استفاده از آن قادر است تا کامیپوتر ها، چراغ های برق و حتی سیستم های گرمایشی را کنترل نماید.
تیم کنن جعبه ای نسبتا بزرگ را در زیر پوست خود قرار داده است. این جعبه عملکردی همچون دست بند های سلامت مثل Fitbit دارد و می تواند اطلاعات بسیاری را در مورد بدن، جمع آوری نماید.
تیم توضیح می دهد برای مثال هنگامی که او تحت استرس باشد، دستگاه این موضوع را متوجه شده و به وسایل موجود در خانه دستور می دهد تا محیطی آرامش بخش را برای او فراهم نمایند. بدین گونه وقتی تیم به خانه می رسد، با یک موسیقی ملایم و وانی پر از آب گرم، مواجه می شود.
یکی از پروژه هایی که انجمن سایبورگ انجام داده است، سنسور ۳۶۰ درجه نام دارد. این دستگاه برای اولین بار در پشت سر مون ریباس، قرار گرفت تا وی را از آنچه که در پشت سرش اتفاق می افتد، مطلع نماید.
سنسور ۳۶۰ درجه هرگاه که فردی از پشت سر ریباس به او نزدیک شود، به حالت ویبره در می آید. این سنسور حتی با دو گوشواره نیز همخوانی دارد و ویبره های خود را به آن ها ارسال می کند. از این طریق و با لرزش گوشواره چپ و یا راست، ریباس می تواند تشخیص دهد فرد مورد نظر در کدام سمت وی قرار دارد.

انجمن سایبورگ، در ادامه فعالیت های خود، قابلیت های جالبی را به پروژه Eyeborg اضافه کرده است. یکی از این موارد Speedborg نام دارد که همچون یک رادار درونی عمل می کند و شما را از سرعت دقیق اجسامی که در برابرتان حرکت می کنند، مطلع می سازد.
نمونه اولیه این دستگاه، در سال ۲۰۰۷ بر روی دست یکی از داوطلبان قرار گرفت.
و باز هم پروژه ای دیگر از انجمن سایبورگ؛ کسانی که انگشت خود را از دست داده اند، می توانند با استفاده از Fingerborg صاحب یک انگشت مصنوعی شوند که در نوک خود مجهز به یک دوربین است. این دوربین به شما اجازه می دهد تا از هر آنچه که میخواهید فیلم برداری کنید و سپس اطلاعات را به کامیپوتر منتقل نمایید.

اوایل دهه هفتاد که دوران دانشگاه رفتن ما بود، بعد از اعلام نتایح کنکور، تقریبا اولین کاری که هر دانشجوی ترماولی میکرد، خرید یک عدد کیف بود. کیفهایی با بدنه محکم و جادار برای گذاشتن کتاب و جزوات.
از اونجایی که توی ایران به دستمال کاغذی میگن کلینکس، به پودر رختشویی میگن تاید وبه مایع ظرفشویی میگن ریکا، به این نوع کیفها هم لقب دادند سامسونت که در واقع نام یک برند تجاری معروف در تولید انواع کیفها و چمدانها بود.
یادم هست نه تنها پسرهای دانشگاه ما، بلکه دخترها هم از این کیفها داشتند. چادر اجباری هم مزید بر علت بود و ترکیب کیف سامسونت و چادرهای برافراشته در برابر باد، بسیار دیدنی.
این روزها دانشجوهای سابق نسبت به دوران دانشجویی و بیپولی، بیشتر درگیر سفر هستند. یکی از دشواریهای مسافرکُش، همانا این طرف و آن طرف کشاندن چمدان در فرودگاههای عظیم دنیاست.
همین ساموسنت عزیز همراه با میکرو موبیلیتی اما کیف سفری جالب رو تولید کرده که ترکیبی از چمدان و اسکوتره. یعنی نه تنها حمل کیف رو آسون میکنه، بلکه حمل خودمون هم آسونتر میشه.
البته سامسونت تنها شرکتی نیست که این نوآوری به ذهنش رسیده و با کمی جستوجو میتونید انواعش رو پیدا کنید.


برای گرفتن عکسهای پانوراما من Photosynth مایکروسافت را ترجیح میدهم، اما اپلیکیشن تازه گوگل برای گرفتن پانوراما که به تازگی برای iOS عرضه شده است، از دو جهت قابل توجه است:
۱- سادگی خیلی زیاد
۲- مزیت بعدی این است که عکسها را مستقیما وارد گوگل مپ کنید و این طوری مناطق دیدنی ایران را جهانی کنید.
پس توصیه میکنم از همین الان این اپ را نصب کنید تا در فرصت بعدی که به یک مسافرت رفتید و از یک مکان دیدنی طبیعی یا یکی از اماکن زیبا دیدن کردید، بتوانید این تجربه را با جهانیان به اشتراک بگذارید.


فید یک پزشک محل مناسبی برای تبلیغات شما: محل تبلیغات متنی و بنری شما
یک هنرمند هلندی به نام «تلمو پیپر» دست به کار جالبی زده است، او پس از ۲۰ سال کار به عنوان یک هنرمند حرفهای، سری به نقاشیهای دوران کودکی خود زده، چند تا از آنها را انتخاب کرده و بعد سعی کرده به مهارتهای دوران بزرگسالیاش، آنها را به تصاویر واقعنمای زیبایی تبدیل کند.
بعد کار جدید و نقاشیهای قدیمی را در کنار هم قرار داده است.










فید یک پزشک محل مناسبی برای تبلیغات شما: محل تبلیغات متنی و بنری شما
امنیت و حریم خصوصی در دنیای امروز، معنی چندانی ندارد. آنچه ما در خلوت میگوییم، دیگر چندان خصوصی نیست. در این پست ما میخواهیم یک دغدغه جدید را مطرح کنیم که تا به حال اصلا تصورش را هم نمیکردیم.
اپلیکیشنهای مختلف در هنگام نصب از ما اجازه میگیرند که در صورت لزوم به حسگرهایی مثل میکروفن یا اطلاعاتی مثل لیست تماسها یا گالری عکسهای دسترسی پیدا میکنند. گرچه خیلی از ماها بدون تأمل، اجازه چنین دسترسیای را ارسال میکنیم و گرچه بعضی از اپهای مشکوک به خصوص در دنیای اندروید، مجوزهایی میگیرند که با عملکردشان سنخیتی ندارد، نفس درخواست اجازه برای دسترسی، کمی به ما آرامش میدهد.
اما جالب است که اپلیکیشنها برای دسترسی به بعضی از حسگرها، اصلا مجوزی لازم ندارند. کدام حسگر، منظورم است؟
ژیروسکوپ
مگر تا حالا شده که موقع نصب یک گیم یا فرضا یک اپلیکیشن پایش کننده حرکات فیزیکی، شما نیاز داشته باشید که مجوز دسترسی به ژیروسکوپ را بدهید؟
نه!
حالا سؤال این است که مگر اطلاعات ژیروسکوپ به چه کار میآیند.
در همایش امنیتی Usenix که هفته پیش برگزار شد، پژوهشگران دانشگاه استنفورد نشان دادند که با ترفندهایی میتوان از ژیروسکوپ گوشی برای استراق سمع استفاده کرد.
ژیروسکوپ به صورت پیشفرض برای سنجش موقعیت گوشی طراحی شده است، اما با نرمافزاری که این محققان نوشتهاند و Gyrophone میتوان ارتعاش حاصل از امواج هوا حین صحبت کردن را تا حد زیادی ثبت کرد!

در حال حاضر کاربران عادی اندروید راهی برای بررسی اپلیکیشنهایی که به سنسور ژیروسکوپ دسترسی دارند، ندارند و همچنین راهی برای باطل کردن این دسترسیها هم وجود ندارد.
مسلم است که با ژیروسکوپ نمیتوان به خوبی میکروفن، به مکالمات گوش کرد. اما پژوهشگران تا حالا هم پیشرفتهای خوبی کردهاند، طوری که میتوانند در ۶۵ درصد موارد، اعداد، در ۸۵ موارد جنسیت گوینده و در ۶۵ درصد موارد، هویت فردی که از بین افراد صحتکننده مشغول ادای یک جمله است را مشخص کنند. با بهبود کارایی نرمافزارهای تشخیص صحبت، میتوان کیفیت استراق سمع را بهتر هم کرد!
ژیروسکوپ گوشیها متشکل از صفحات بسیار کوچک در حال ارتعاشی است که روی یک تراشه سوار شدهاند. اما علاوه بر حرکات، ارتعاش حاصل از برخورد امواج هوا هم میتواند روی آنها اثر بگذارد. در سیستمهای اندرویدی، ژیروسکوپ به فرکانسهای تا ۲۰۰ هرتز حساس است و از آنجا که فرکانس صحبت آدمها معمولا بین ۸۰ تا ۲۵۰ هرتز است، قسمت قابل ملاحظهای از صحبتها توسط ژیروسکوپ، میتوانند آشکار شوند.

در iOS ژیروسکوپها تنها تا ۱۰۰ هرتز حساس هستند و بنابراین از ژیروسکوپ در iOS برای استراق سمع نمیتوان بهره زیادی برد.
نگرانی ما نباید تنها معطوف به اپلیکیشنهای native باشد، اپلکیشنهای وبی که ما با استفاده از مرورگرها آنها را اجرا میکنیم، ممکن است با دسترسی به ژیروسکوپ بالقوه خطرناک باشند. بنابراین باید نگاهی به وضعیت امنیتی مرورگرهای اینترنتی خودمان هم داشته باشیم.
در این میان وضعیت مرورگر فایرفاکس برای اندروید از همه بدتر است: در شرایطی که مرورگر کروم و سافاری، تنها مجوز دسترسی به اطلاعات ژیروسکوپها را تا ۲۰ هرتز میدهند، مرورگر فایرفاکس اجازه دسترسی تا ۲۰۰ هرتز را دارد. بنابراین اگر شما یک کاربر اندروید باشید و از مرورگر فایرفاکس استفاده کنید، بدون نصب هیچ اپلیکیشنی، صرفا با ورود به سایتی که یک قطعه کد جاوااسکریپت روی آن نصب شده، ممکن است مورد جاسوسی قرار بگیرید!
گوگل میتواند به سرعت مشکل امنیتی اخیر را با محدود کردن فرکانسهای قابل دسترسی مجاز برطرف کند. همچنین باید در مورد اپهایی که نیاز به دسترسی غیرمحدود به ژیروسکوپ را دارند، از کاربر اجازه خواسته شود. اصولا در مورد گیمها نیازی به دسترسی به فرکانسها تا ۲۰۰ هرتز وجود ندارد.
فید یک پزشک محل مناسبی برای تبلیغات شما: محل تبلیغات متنی و بنری شما

بازی های ویدئویی ذاتاً بیش از تمامی دیگر گجت ها و یا اسباب بازی ها درآمد زا هستند زیرا به سطح مخاطب گسترده تری دسترسی دارند. همچنین پیشرفت های اخیر فناوری و توسعه روز افزون ادوات همراه هم مزید بر علت شده اند. امروزه اگر گیمر حرفه ای نباشید حتماً تلفن همراه هوشمندتان بخشی از وقت شما را با سر و کله زدن با بازی ها می گیرد.
پایگاه خبری فناوری اطلاعات برسام
پایگاه خبری فناوری اطلاعات برسام -
اگر اطلاع داشته باشید روز گذشته هنرمند محبوب، رابین ویلیامز در سن ۶۳ سالگی در گذشته است. او یکی از بهترین بازیگران فیلم های هالیوودی بود و رابطه خوبی نیز با اپل داشت. حالا با این رخداد، اپل یک صفحه در وبسایت خود به فوت این بازیگر اختصاص داده است.
پیش از این، اپل برای فوت نلسون ماندلا نیز صفحه ای در سایت خود ایجاد کرده بود.
در کنار این صفحه در سایت اصلی اپل، یک صفحه هم در فروشگاه آیتونز ساخته شده است که آثار این هنرمند لیست شده تا افراد با این شخص آشنایی بیشتری داشته باشند.
منبع:آیفون
شاید داستان جنایتکاران ساده و ناشی را بارها و بارها شنیده باشید اما جنایتکار داستان امروز ما حکایت دیگری دارد! به احتمال فراوان چهره یک جنایتکار که با ماسکی صورت خود را پنهان کرده است در ذهن شما نقش بسته است اما میان جنایتکاران و قاتلان با دنیای ابزارهای همراه نتوانسته اید پلی برقرار کنید.
جالب است بدانید که جنایتکار داستان امروز ما، دستیار صوتی اپل را به عنوان شریک جرم خود انتخاب کرده است!

ماجرا به دیروز برمی گردد که طی آن ابعاد تازه تری از پرونده “Pedro Bravo” که دانشجوی دانشگاه فلوریدا است آشکار شده است. این دانشجو، از متمهان اصلی قتل همکلاسی وی، “Christian Aguilar” که در سال ۲۰۱۲ به قتل رسیده است به شمار می رود.
جالب است بدانید که شواهدی به دست آمده است که Pedro Bravo، در شب حادثه به سراغ Siri رفته و عبارت “I need to hide my roommate” (من نیاز به پنهان کردن هم اتاقی ام دارم) را پرسیده بود. مدارک جدیدی نیز به دست آمده است که حکایت از روشن شدن فلاش آیفون وی به مدت ۴۸ دقیقه، آن هم در شب وقوع قتل Christian دارد.
گفتنی است که “location data” (داده های مکانی) آیفون Pedro Bravo نیز با آن چه که خود اعتراف کرده است در آن شب حادثه کجا بوده است مطابقت ندارد.
اما بد نیست بشنوید از پاسخ شریک جرم این متهم ریف اول! سیری در پاسخ به این سوال کزایی، از Pedro Bravo سوال کرده است که به دنبال چه نوع مکانی هستید؟ مرداب، مخازن، یا ریختهگری فلز؟
گویا اپل پس از متوجه شدن از این ماجرا و جهت پیشگیری از هرگونه مشکلات قانونی احتمالی، به سیری فرمان داده است تا در پاسخ به این سوال عجیب، عبارت “What, again” (چی؟ دوباره بگو!) را نشان دهد.
» منبع : phonearena «

شما می توانید تلفن همراه یا تبلت اندرویدی خود را با استفاده از صفحه کلید و موشواره در کامپیوتر تان کنترل کنید. چه بخواهید به پیام های تان با استفاده از صفحه کلید کامپیوتر پاسخ دهید و یا بخواهید از تبلت تان به عنوان یک صفحه ی نمایش دوم در کنار صفحه ی نمایش کامپیوتر استفاده کنید، این راه اندازی برای تان مانند یک جادو عمل خواهد کرد. و یا حتی می توانید یک متن را در یک دستگاه کپی کرده و آن را در دستگاه دیگر Paste نمایید.
نرم افزار Synergy این انجام این کار را در کامپیوترهای ویندوز، مک و لینوکس امکان پذیر کرده است تا با استفاده از آن بتوانید از صفحه کلید و موشواره ی کامپیوتر به صورت اشتراکی استفاده کنید. این کار بسیار ظریف و یکپارچه انجام می گیرد : کافی است اشاره گر موشواره را به گوشه ی یکی از صفحه ی نمایش ها ببرید و پس از آن بلافاصله می توانید کنترل دستگاه دیگری را در اختیار بگیرید. اگر دو کامپیوتر در کنار هم روی میز کاری تان داشته باشید، این روش برای تان بسیار مفید و کارآمد خواهد بود.

البته اکثر مردم معمولا از چندین کامپیوتر بر روی میز خود به صورت همزمان استفاده نمی کنند، اما داشتن یک تلفن همراه یا تبلت اندرویدی در کنار کامپیوتر تان، چیزی غیرعادی نیست. اگر می خواهید آن دستگاه ها (تلفن همراه یا تبلت) را با استفاده از صفحه کلید و موشواره ای که با آن ها از کامپیوتر خود استفاده می کنید، کنترل نمایید، نسخه ی اندرویدی نرم افزار Synergy دقیقا همان چیزی است که به آن نیاز خواهید داشت.
برای استفاده از نسخه ی اندرویدی نرم افزار Synergy، حتما باید دستگاه خود را روت (Root) کرده باشید، وگرنه به هیچ شکل دیگری نمی توانید از آن استفاده کنید. همچنین باید بدانید که این اپلیکیشن در برخی از دستگاه ها دارای باگ است و به صورت مداوم بسته می شود.
برای شروع کار، نسخه ی دسکتاپ نرم افزار Synergy را برای کامپیوتر و نسخه ی اندرویدی آن را برای تبلت یا تلفن همراه تان دانلود کرده و آن ها را نصب کنید.
اکنون به سراغ بخش فنی کار می رویم. باید بدانید که دو بخش اصلی برای راه اندازی Synergy وجود دارد : سرور (Server) و کلاینت (Client).
این بخش ها آنگونه که به نظر می رسند، پیچیده نیستند. سرور همان دستگاهی است که با استفاده از آن می خواهید دستگاه دیگری را کنترل کنید و در واقع همان دستگاهی که به صفحه کلید و موشواره متصل است. در این راه اندازی، احتمالا منظور از سرور همان کامپیوتر شما خواهد بود. کلاینت در واقع دستگاهی است که با استفاده از صفحه کلید و موشواره ی دستگاه دیگر کنترل می شود و در اینجا همان تلفن همراه یا تبلت اندرویدی شما است.
در ابتدا به سراغ راه اندازی سرور می رویم. ابتدا نرم افزار Synergy را اجرا کنید، سپس کامپیوتر خود را به عنوان سرور انتخاب کنید. پس از آن باید نحوه ی مرتب سازی و کنار هم قرار گرفتن صفحات نمایش را در برنامه مشخص کنید :

سرور شما در وسط نمایش داده می شود (localhost). دستگاه اندرویدی خود را – که با نام android در نرم افزار نشان داده شده – در هر طرف دلخواه از مرکز قرار دهید. راه اندازی نرم افزار در مک به این شکل است، اما گزینه ها و تنظیمات مربوط به آن در لینوکس یا ویندوز تفاوت زیادی با مک ندارند. همچنین می توانید نام دستگاه اندرویدی خود را نیز تغییر دهید، یک نام برای آن قرار داده (مانند “Android”) و آن را به خاطر بسپارید.
وقتی همه ی تنظیمات را به گونه ی دلخواه خود انجام دادید، IP سرور خود را یادداشت کنید.

پس از برداشتن IP سرور، روی گزینه ی “Start” کلیک کنید. پس از آن به سراغ اپلیکیشن Synergy در دستگاه اندرویدی می رویم.

مطمطئن شوید که نام وارد شده در قسمت Client Name، همان نامی باشد که در بخش تنظیمات صفحه ی نمایش در سرور برای دستگاه تان انتخاب کردید. اگر مطابقت نداشت، آن را تغییر دهید. در قسمت بعدی (Server IP/Hostname)، آی پی سرور خود را که یادداشت نمودید، وارد کنید و مقدار وارد شده در قسمت Server Port را بدون تغییر بگذارید. پس از آن می توانید گزینه ی “Connect” را انتخاب کنید.
اگر همه چیز به درستی کار کند، شما خواهید توانست که نشانه گر موشواره را از کامپیوتر به صفحه ی دستگاه اندرویدی جابجا کنید. در بسیاری از دستگاه ها به دلیل باگ های موجود در اپلیکیشن، هنگام کار با آن با کرش های مداوم و منظمی مواجه می شوید. البته بروز رسانی های مربوط به نسخه ی کلاینت به زودی ارائه می شوند که می توانند مشکل را حل کنند.
اگر صفحه ی نمایش دستگاه شما به صورت مداوم خاموش شود، این شکل از راه اندازی کمتر کاربردی خواهد بود. به همین دلیل توصیه می کنیم که در کنار Synergy، اپلیکیشن Wakey را نیز روی دستگاه تان نصب کنید.

این کار باعث می شود که از خاموش شدن صفحه جلوگیری شود، که در واقع برای استفاده از دستگاه به عنوان صفحه ی نمایش دوم به آن نیاز خواهید داشت.
اکنون یاد گرفتید که چگونه نرم افزار را راه اندازی کنید، اما برای چه کاری می توانید از آن استفاده کنید؟ اگر از تبلت خود برای کارها و مشاغل تولیدی و بهرهوری استفاده می کنید، ممکن است ایده هایی برای استفاده از این سیستم داشته باشید. در زیر می توانید برخی از کاربردهای آن را ببینید :
شما از این شیوه برای انجام چه کاری استفاده می کنید؟ نظرات و ایده های خود را با ما به اشتراک بگذارید.
منبع : MakeUseOf.com با ویرایش از گویا آی تی

کمپانی کینگستون پیشروترین شرکت مستقل در زمینه تولید انواع حافظه روز گذشته حافظه رم با عملکرد بالای HyperX Savage را معرفی کرد. این محصول جدید قرار است جایگزین رم های HyperX Genesis شود تا برای کاربران، گیمرها و طراحان تجربه ای جدید را فراهم آورد.
کاربرانی که در مورد اپل و محصولاتش در وبلاگها، فورومها و شبکههای اجتماعی مینویسند به کرات از اسکرین شات استفاده میکنند.
اما در این میان خیلیها دوست ندارند که در همین اسکرینشاتها، وضعیت وای فای، باتری یا میزان خطدهی آیفون یا آیپدشان، مناسب نشان داده نشود.
بله! کاربران اپل این کمالگرایی را دارند و خود اپل هم چنین تمایلی دارد.
در نسخه تازه سیستم عامل مک یعنی Yosemite این امکان مهیا شده که وقتی تصویر صفحه نمایش آیدوایس خود را به کمک نمایش میدهید یا اصلاحا mirroring میکنید با نرمافزار QuickTime تصویر را ضبط کنید.
جالب این است که در تصویر ضبط شده همیشه میزان شارژ باتری ۱۰۰ درصد نشان داده میشود و میزان خطدهی و وای فای همیشه کامل است، حتی اگر عملا و در واقع بیشتر از ۵ درصد شارژ وجود نداشته باشد یا وضعیت وای فای یا خطدهی خوب نباشد.

تقلب کوچکی در جهت، ایدهآل نشان دادن آیدیوایسها!
فید یک پزشک محل مناسبی برای تبلیغات شما: محل تبلیغات متنی و بنری شما
«... به دلیل وجود مشکلات فراوانی که برای انتقال در آمدها به درون کشور وجود دارد، بسیاری از برنامهنویسان و طراحان ایرانی که به شکل انفرادی (فریلنس) فعالیت دارند مجبور هستند قید چنین بازارهای پر سودی را بزنند ...»
محمد قصاع: هدف از نگارش این مقاله بررسی جایگاه ادبیات علمی- تخیلی در گسترۀ ادبیات داستانی بعد از سال ۱۳۵۷ است.
تعاریف گوناگونی از ادبیات علمی -تخیلی وجود دارد. با نگاهی به داستانهای کوتاه و رمانهای علمی- تخیلی میتوان موارد اصلی کاربری این شاخۀ ادبی را به شرح زیر برشمرد:
الف- بیان نظریههای علمی ثابتشده یا ثابتنشده در قالب داستان و ارائۀ پیشبینیهایی از آینده و پیشرفت آتی علم و فناوری و گمانزدن علمی دربارۀ مسائل علمی انسانی و اجتماعی در گذشته، حال یا آینده.
اغلب نویسندگانی که از این کاربری استفاده کردهاند، دانشمندانی شناختهشده در علوم فیزیک، ریاضی و نجوم هستند یا دستکم در یکی از رشتههای علمی تخصص بسیار دارند. تعدادی از این نویسندگان عبارتند از ژول ورن، هوگو گرنسبک، آرتور سیکلارک، ایزاک آسیموف، لری نیون، گریگوری بنفورد، پل اندرسون، دیوید برین، جنتری لی.
همین کاربری است که عدۀ زیادی از جوانان را به سمت علم و تحقیق و طرح سؤال جذب و جلب میکند. تعداد زیادی از دانشمندان امروز غرب، در دوران جوانی با عشق و علاقه و کنجکاوی فراوان، داستانهای علمی- تخیلی مطالعه میکردهاند.
ب- بیان تأثیر نظرات علمی و پیشرفت علم و فناوری و گاه حتی سقوط و نزول علم تجربی، بر جوامع و انسانها در آینده به منظور شناسایی مشکلات نسلهای آینده و ارائۀ راهحلهای نظری و اعلام خطر به جوامع در قالب داستان.
شاید تعجبآور باشد اما حقیقت این است که مسائلی مانند آلودگی محیط زیست و ازدیاد جمعیت، تسلط ماشین بر انسان، تأثیر مخرب رایانهها بر روح و روان و رفتار انسانها و اثرات پیشرفت لگامگسیخته و بیهدف صنعت و سرمایهداری برای نخستین بار در همین داستانهای علمی- تخیلی مطرح شدهاند. به همین دلیل است که عدهای به درستی ادبیات علمی- تخیلی را یکی از انسانیترین شاخههای ادبیات داستانی میدانند.
در این گروه میتوان به نویسندگانی مانند رابرت ا.هینلین، روبرت سیلوربرگ، ری برادبری، فرانک هربرت، اچ.جی.ولز، فلیپ ک.دیک، هری هریسون، کارل چابک اشاره کرد.
پ- ایجاد بهت و شگفتزدگی و برانگیختن حیرت و غافلگیرکردن خواننده و ایجاد تعلیق، شاید این یکی از مهمترین کاربریهای اولیۀ چنین داستانهایی باشد که به طور ویژه در داستانهای کوتاه خودنمایی میکند. حالت شگفتزدگی در خواننده با ایجاد چرخشهای ناگهانی و غیرمنتظره در طرح داستان، آن هم به دلیلی منطقی و علمی به دست میآید. به همین دلیل است که چنین داستانهایی از جذابیت خارقالعادهای برخوردار هستند.
بدون تردید یکی از مهمترین استادان استفاده از این کاربری، ادگار آلنپو است و اغلب داستانهای علمی- تخیلی او چنین خصلتی دارند. او انگیزش بهت را حتی به داستانهای پلیسی نیز تعمیم داد و آگاتا کریستی نیز به او تأسی جسته است. علاوه بر او میتوان از نویسندگان دیگری نام برد؛ از جمله ری برادبری، ایزاک آسیموف.
در داستانهای علمی- تخیلی، گاه جنبۀ داستانپردازی یا قصهگویی یا ماجراپردازی غالب است، گاه مباحث نظری و علمی خط قالب بر داستان میشود و گاه نویسنده، بیش از هر چیز به بیان تخیلاتش میپردازد. تقویت ماجراسازی و قصهگویی، رمان علمی- تخیلی را به پیکرۀ اصلی ادبیات داستانی نزدیک میکند؛ به گونهای که گاهی فقط به وسیله کارشناسان، قابل تشخیص میشوند.
از طرفی دیگر، تقویت بعد تخیل، داستان را به سمت شاخۀ ادبی تخیلی یا فانتزی سوق میدهد. هرگاه مسائل علمی داستان، اصول ثابتشده علمی باشد، آن را داستان علمی مینامند. به هر حال شدت و ضعف هر بعد، یعنی داستانی، علمی و تخیلی، آنها را از ادبیات علمی- تخیلی دور نمیکند، بلکه در مجموع طیفی از داستانهای علمی- تخیلی با شدت و ضعف در زمینههای متفاوت به وجود میآید.
مهمترین عناصر و مضامین مطرح در ادبیات علمی- تخیلی:
۱- سفر در زمان
۲- سفر در فضا و سیارات و کهکشانهای دیگر
۳- سفر در زمان و فضا
۴- سفر به ابعاد دیگر
۵- داستانهای آرمانشهری، ضد آرمانشهری و زمانشهری
۶- روباتها
۷- جنگهای فضایی
۸- خلق یا اکتشاف دنیاهای جدید
۹- زمینگونهسازی
۱۰- موجودات بیگانه یا فضایی در انواع هوشمند یا غیرهوشمند، جانوری، گیاهی، متخاصم، دوست یا بیاعتنا
۱۱- اصلاح و تغییر ژنتیکی
۱۲- اَبَرانسانها
۱۳- نیروهای ویژۀ انسانی مانند تلهپاتی، روحی و …
۱۴- علوم فضایی، اخترشناسی
۱۵- سفینههای فضایی
۱۶- اسلحههای پرتویی، غیرمتعارف و نو
۱۷- مبارزۀ علمی با بلایا و جبرهای طبیعی
۱۸- حکومت واحد جهانی
۱۹- ارائۀ پیشنهادهای علمی غیرمتعارف مانند آسانسور فضایی و …
۲۰- مسکونیسازی سیارههای دیگر
۲۱- ایستگاههای فضایی
۲۲- نخستین تماس و برخورد با موجودات فضایی و چگونگی آن
و …
تعداد عناصر و مواد داستانی علمی- تخیلی بسیار زیاد و متنوع است و با ظهور هر نویسنده مبتکر جدید بر تعداد آن افزوده میشود. ما در اینجا فقط به موارد عمده، اشاره کردیم. البته لازم به ذکر است که در رمانها، اغلب از ترکیبی از تعدادی از عناصر فوق استفاده میشود.
شروع ادبیات علمی- تخیلی در ایران
همۀ علاقهمندان به این شاخۀ ادبی و کسانی که موجودیت و ارزش این شاخۀ ادبی را به رسمیت نمیشناسند و آن را حتی مضر هم میدانند، دربارۀ زمان و چگونگی ظهور و رشد ادبیات علمی- تخیلی در ایران، اشتراک نظر دارند. آنها معتقدند ادبیات علمی- تخیلی از پنج یا در نهایت شش دهه پیش با ترجمۀ آثار ژول ورن وارد ایران شد و با استقبال جوانان و نیاز روزافزون بازار به اینگونه کتابها و داستانها باعث افزایش ترجمه چنین داستانهایی شد. آنها نیز مانند کارشناسان و منتقدان غربی بر این باورند که ادبیات علمی- تخیلی جدید در اواخر قرن هجدهم میلادی در اروپا متولد شده و در آمریکا رشد یافته است و در ایران هیچ سابقه و ریشهای ندارد و وارداتی است. در اینجاست که آنها به دو دسته تقسیم میشوند. عدهای به آن علاقهمند شده و خواهان واردات بیشتر هستند و عدهای دیگر با نگرانی خواستار توقف واردات و تعطیلی این شاخۀ ادبی هستند و انواع و اقسام برچسبها، که گاه هیچ ربطی به نقد ادبی ندارند، بر آن میزنند.
ولی آیا به راستی این گمان صحیح است؟ آیا ادبیان ایران کهن و چه ادبیات معاصر پارسی با آنچه که امروز ادبیات علمی- تخیلی نامیده میشود، بیگانه است؟
با کمی تحقیق و تفکر به راحتی و با اطمینان خاطر میتوان گفت که این گمان، اشتباه و خطاست. بروز چنین اشتباهی ناشی از دو دلیل مهم است. نخست عدم آشنایی و شناخت محتوایی از ادبیات علمی- تخیلی و دیگر نادیدهگرفتن موقعیت زمانی و مکانی نویسندگان و زمان نگارش داستانها.
اگر با دو ابزار فوق به ادبیات کهن و معاصر پارسی رجوع کنیم، میتوانیم تعداد زیادی داستان علمی- تخیلی بیابیم البته بدون آنکه چنین نامی بر خود داشته باشند. از جمله داستان پرواز کیکاووس و جام جم در شاهنامۀ فردوسی و داستان حیبنیقظان که به وسیلۀ چند نویسنده از جمله ابنسینا نوشته شده است.


اینگونه داستانها با پیشرفت علوم تجربی در دنیای اسلام ظهور و بروز یافتند و رشد کردند و با رکود و نزول آن، به خاموشی گراییدند. تا همین پنجاه یا شصت سال پیش و از حدود نیم قرن پیش که ایرانیان بار دیگر به فراگیری علم روی آوردند، زمینه برای ظهور داستانهای علمی- تخیلی نیز فراهم شد. با توجه به اینکه حیات ادبیات علمی- تخیلی وابسته به حیات و گسترش و پیشرفت علم است، ورود و ظهور مجدد اینگونه داستانها همگام با پیشرفت علم در ایران، همراه و اجتنابناپذیر شد. پس در واقع در ایران آنچه بر این شاخۀ ادبی رفته است، انقطاع یا گسستگی تاریخی است، نه عدم وجود سابقه تاریخی.
به نظر میرسد نخستین آثار علمی- تخیلی که به زبان فارسی ترجمه شد، کتابهای ژول ورن بود. او یکی از بنیانگذاران ادبیات علمی- تخیلی در غرب محسوب میشود. باید توجه داشت که او در دورانی کتاب مینوشت که هنوز نام «علمی- تخیلی» برای این گونه داستانهای علمی ابداع و انتخاب نشده بود. این کار به وسیله هوگو گرنسبک در دهۀ دوم قرن بیستم انجام شد. تمام آثار ورن به فارسی ترجمه شدهاند، گاه به طور کامل و اغلب مثلهشده، آن هم به دور از ظرافتها و اصول ترجمه. بیشتر این مترجمان با بینش و تفکر علمی- تخیلی بیگانه بودند و به صورت تخصصی با این شاخۀ ادبی روبهرو نمیشدند.
به غیر از ژول ورن، بعضی کنابهای جک لندن مانند «پاشنه آهنین» و «طاعون سرخ» که با بینش ضدآرمانشهری و توجه به «دوران پس از فاجعه» نوشته شده است، ترجمه شده و تأثیر خوبی بر جا گذاشتند. در ضمن میتوان به کتاب سفرنامۀ گالیور و آثار ولتر مانند «میکرومگاها» و «کاندید» اشاره کرد.
تعدادی داستان کوتاه ترجمهای و مقاله «به ویژه درباره بشقابپرندهها» از ذبیحالله منصوری نیز باقی مانده است.
با پیشرفت جهشی هنر هفتم یعنی سینما، که به شدت مورد استقبال ایرانیان قرار گرفت و با حضور گستردۀ تفکر علمی- تخیلی در این عرضه، ناگهان اندیشۀ علمی- تخیلی جدید، به وسیله فیلم و سینما وارد ایران شد. این فیلمها که عدۀ زیادی آنها را به غلط فیلمهای فضایی مینامند، نظر همه به ویژه جوانان را جلب کرد. از میان این فیلمها مجموعه «پیشتازان فضا» -که هنوز هم در آمریکا تولید میشود- و فیلم «۲۰۰۱، یک اودیسۀ فضایی» از مقبولیت ویژهای برخوردار شدند.
در سال ۱۳۴۹ انتشارات جیبی، کتاب «راز کیهان» نوشته آرتور سی.کلارک را با ترجمه پرویز دوایی چاپ کرد. «راز کیهان» در اصل، همان کتاب «۲۰۰۱، یک اودیسۀ فضایی» نوشته آرتور سی.کلارک است که به وسیلۀ استنلی کوبریک به فیلم تبدیل شد، فیلمی که همیشه در خاطر علاقهمندان به سینمای علمی- تخیلی باقی خواهد ماند. این کتاب مهمترین اثر ترجمهشدۀ علمی- تخیلی پیش از انقلاب است و تأثیر آن بر علاقهمندان، مترجمان و نویسندگان داستانهای علمی- تخیلی کنونی ایران انکارناپذیر است. همچنین میتوان از کتابهای «شهر طلا و سرب» و «برکۀ آتش» نوشته جان کریستوفر نام برد که با توجه به گرایش آنها به گرده سنی نوجوان به وسیله کانون پرورش فکری کودکان و نوجوانان به چاپ رسیدند. از همینجا بود که ترجمه آثار علمی- تخیلی کمکم شروع شد و با استقبال خوانندگان روبهرو شد.
در زمینه تألیف، نردیکترین آثار به ادبیات علمی- تخیلی، بعضی کتابهای صادق هدایت است که عبارتند از:: «پیش از آدم»، «میمونهای کوه دماوند» و «گاف.لام.میم» البته به شرط آن که نیهلیسم و پوچگرایی را از آن داستانها جدا و دور کنیم، چرا که ادبیات علمی- تخیلی به لحاظ ماهوی با نیهیلیسم همگرایی ندارد. بنابراین در زمینه آثار تألیفی علمی- تخیلی در دوران پیش از انقلاب، ایران دچار فقر جدی بود.
به این ترتیب ادبیات علمی- تخیلی گرچه پیش از انقلاب و طی دوران سهساله ظاهر شد، اما وجودش بیشتر مدیون فیلم و سینما بود و به لحاظ ادبی نه به یک جریان تبدیل شد و نه چیزی برای نقد و بررسی داشت و در این زمینه نه مجلهای چاپ میشد و نه انجمن یا کانون وجود داشت، حتی مترجم یا نویسندهای که به طور تخصصی در این زمینه کار کند، وجود نداشت.
یکی دو سال پس از انقلاب و در پی وقفهای کوتاه، بار دیگر ترجمۀ داستانها و رمانهای علمی- تخیلی با حرکتی آهسته شروع شد. مترجمان –که تعدادشان کم بود- جسته و گریخته کتابهایی از آرتور سی.کلارک و ایزاک آسیموف را ترجمه کردند. به این ترتیب تا چند سال، سالی ۲ تا ۵ عنوان کتاب علمی- تخیلی ترجمه و منتشر میشدند.
حرکت پسندیده و مؤثر دیگر، اقدام مجلۀ «دانشمند» بود که افزون بر چاپ ویژهنامۀ علمی- تخیلی، چند داستان کوتاه علمی- تخیلی ترجمهای را نیز به چاپ رساند. این مجله که در آن دوران جایگاه ویژهای میان دانشجویان و دانشپژوهان داشت، علاقۀ جوانان را به این داستانها برانگیخت و به طور غیرمستقیم بر روند رشد این آثار در بازار کتاب تأثیر گذاشت. ظاهراً مجلۀ «دانستنیها» که مورد علاقۀ جوانان بود نیز چند داستان کوتاه در همان سالهای ابتدایی نشر خود به چاپ رساند و در همین مدت هم فیلمهای علمی- تخیلی، کماکان به تأثیرگذاری و جلب جوانان به سوی اندیشه و تفکر علمی- تخیلی ادامه میدادند.

اما تحول اساسی از حدود نیمه دوم دهه ۶۰ پیش آغاز شد، زمانیکه تعدادی از همان جوانان علاقهمند به داستانها و فیلمهای علمی- تخیلی به طور جدی به کار ترجمه اینگونه کتابها همت گماشتند و اغلب به یک یا دو کار بسنده نکردند. ناشران نیز که با موج علاقۀ نوجوانان و جوانان به این شاخۀ ادبی روبهرو شده بودند، به نشر آثار ترجمه آنان پرداختند.
تعدادی از این مترجمان عبارتند از: پیمان اسماعیلیان خامنه، محمد قصاع، ناصر بلیغ، حسین ابراهیمی (الوند)، هوشنگ غیاثی، حسن اصغری و شهریار بهترین.
توجه: بسیار مایلم در «یک پزشک» به نحوی با این مترجمان به نام و تأثیرگذار ارتباط برقرار کنم و اگر بشود در قالب پستهایی با آنها مصاحبههایی داشته باشم. اگر توانایی برقراری این ارتباط را دارید، بسیار ممنونم میشوم این لطف را در حق من و خوانندگان یک پزشک بکنید.
البته مترجمان دیگر هم هستند که یک یا دو کار ارائه دادهاند اما معرفی تمام آنها در این مختصر امکانپذیر نیست. در همین زمینه، مهمترین ناشران عبارتند از: نشر افق، شقایق، نقطه، پاسارگاد و مرکز چاپ و نشر بنیاد. بعضی ناشران نیز یک یا دو کار علمی- تخیلی به چاپ رساندهاند، ولی نه به صورت حرفهای و تخصصی.
به این ترتیب تعداد زیادی عناوین جدید از کتابهای علمی- تخیلی به خوانندگان عرضه شد و هنور هم عرضه میشود. از طرفی با ترجمۀ اغلب آثار کلارک و آسیموف و به دلیل توجه و نیاز خوانندگان، اکنون از نویسندگان دیگری که اغلب در غرب، از جایگاه بالایی برخوردارند، کتابهایی ترجمه شده و میشود؛ از جمله ری برادبری، روبرت سیلوربرگ، هینلین، اچ.جی.ولز و پل اندرسون.
اما در زمینۀ داستانهای کوتاه، افزون بر چاپ کتابهای مجموعهای، مجلات نیز گاه و بیگاه داستانهایی چاپ کردهاند، اما نه به صورت منظم و همیشگی.
تا آنجا که نگارنده مطلع است، به غیر از آثار ژول ورن، تاکنون بیش از صد عنوان کتاب علمی- تخیلی در ایران چاپ شده است که به جز تعدادی انگشتشمار، همگی مربوط بعد از سال ۵۷، به ویژه بین سال ۶۵ تا ۷۷ هستند.
اندیشه و جریان رشد ادبیات علمی- تخیلی در ایران دچار سه نقطهضعف اساسی نیز هست:
الف- عدم وجود انجمن یا کانون و مجلۀ کاغذی ویژۀ این شاخۀ ادبی. هماکنون در آمریکا و کشورهای اروپای غربی و شرقی، مجلههای علمی- تخیلی با شمارگان بسیار زیاد و عناوین متنوع چاپ و منتشر میشوند اما در ایران چنین مجلهای وجود ندارد. (خوشبختانه به یاری اینترنت، شاهد انتشار مجلههایی دیجیتال در حیطه داستان علمی تخیلی بودهایم، اما مسملما این کافی نیست.)
از انجمنها و کانونهای علمی- تخیلی به شیوهای که در غرب بسیار رایج هستند، اثری وجود ندارد. این انجمنها مکانی برای تبادل افکار، بحث و نقد نظرات و حتی ارائۀ نظریههای علمی هستند به گونهای که تعدادی از آنها با مراکز تحقیقاتی مهم دنیا از جمله ناسا در ارتباطند. همین انجمنها با اهدای جوایز به نویسندگان و هنرمندان به گسترش هنر و ادبیات و اندیشۀ علمی- تخیلی کمکهای انکارناپذیری میکنند.
ب- کمبود آثار تألیفی، ظهور و رشد ادبیات علمی- تخیلی جدید، چه پیش از انقلاب و چه پس از آن، مدیون آثار ترجمهای است. با گذشت زمان، اشتیاق خوانندگان باعث رشد ترجمۀ کتابهای جدید علمی- تخیلی غربی شد. اما بسیار طبیعی است که نویسندگان غربی کتابهایشان را با توجه به اصول فرهنگی، فکری، اجتماعی، اخلاقی و حتی سیاسی و اعتقادی خود مینویسند و طبیعی است که گاه اصول مورد توجه آنها با فرهنگ اسلامی- ایرانی تفاوت داشته باشد.
به طور مختصر اشاره شد که در ادبیات کهن پارسی ردی قوی از داستانهای علمی- تخیلی و فانتزی (تخیلی) وجود دارد که انکارناپذیر است ولی این امر به دلیل انقطاع یا گسیختگی تاریخی نادیده گرفته میشود.
از طرفی دیگر، یکی از وظایف ادبیات علمی- تخیلی جستوجو و یافتن و پیشبینی مشکلات بشری در آیندههای دور و نزدیک و پیداکردن راهحلهای آن است که از این لحاظ ماهیتی انسانی دارد و درست به همین دلیل با دین و مذهب بیگانه نیست. هستند نویسندگانی غربی که میانۀ خوبی با مذهب ندارند اما مترجمان ایرانی تاکنون کتابی از آنها ترجمه و چاپ نکردهاند.
آیا میتوان آرتور سی.کلارک را فردی ضدمذهبی نامید؟ کتابهای «پایان طفولیت»، مجموعۀ چهارجلدی «اودیسه»ها و مجموعه چهارجلدی «راما»ها و «ریشتر۱۰» مفاهیمی عرفانی ارائه میدهند. اصولاً کسانی که دارای اندیشه و ذهنیت علمی- تخیلی هستند، به هستی با دیدی کلان مینگرند. دید کلان به هستی، با مفاهیمی مانند شعور مطلق حاکم بر هستی، خودآگاهی هستی، ذات هستی، روح هستی و یا در نهایت با مفهوم خدا بیگانه نیست.
شاید مهمترین ابزار برای رفع بینشهای غلط، ارائۀ آثار تألیفی با مشخصات و خصوصیات فرهنگی- اعتقادی و منطبق بر افکار ایرانی- اسلامی باشد. همینجا است که با ضعف عمدۀ این شاخه ادبی در ایران روبهرو میشویم.
نگارنده با وجود پیگیری و جستوجوی فراوان، به غیر از چند داستان که با کمی اغماض و صرفنظر از بعضی مسائل تخصصی شاید بتوان علمی- تخیلی نامیدشان، هیچ اثر تألیفی در پیش از انقلاب نیافت. در ده سال ابتدای انقلاب نیز به غیر از دو اثر از آقایان محمود حکیمی و خلخالی که فقط برای ایجاد جذابیت از تعدادی عناصر داستانی علمی- تخیلی استفاده کرده بودند، چیزی یافت نشد. این آثار نیز به لحاظ محتوایی، علمی- تخیلی نبودند، بلکه ماهیتی سیاسی- دینی- عقیدتی داشتند.
با افزایش آثار علمی- تخیلی و ایمان جوانان ایرانی به توانایی و خلاقیت خود، لزوم خلق آثار تألیفی بر کارشناسان، آشکار و مسلم شد و کمکم تعدادی از نویسندگان که متوجه علاقۀ جوانان به این شاخۀ ادبی شده بودند، تلاش کردند از این قالب برای نوشتن داستان استفاده کنند، اما هیچیک از این آثار به جز پوستهای نازک، شباهتی با آنچه ادبیات علمی- تخیلی نامیده میشود، نداشت.
خوشبختانه طی ۱۵ سال اخیر، این طلسم شکسته شد و ما شاهد انتشار تعدادی کتاب رمان و داستان کوتاه در این زمینه در مجلات بودهایم.
شاید شروع واقعی این راه را بتوان کتاب «جهش خاطرات روز بعد» نوشتۀ محمد قصاع (نویسنده همین مقاله)، که توسط نشر البرز چاپ شد، دانست. من (قصاع) در این کتاب علاوه بر توجه به محتوایی به ادبیات علمی- تخیلی و رعایت اصول این شاخۀ ادبی، به اصول فرهنگی شرقی- اسلامی نیز توجه کردهام. در ضمن داستان کوتاه «تماس» این جانب نیز در مجلۀ «ادبیات داستانی» چاپ شده است.
کتاب دیگری را که میتوان مورد توجه قرار داد، «آخرین بنیاد کهکشانی» ترجمه و تألیف داوود ارکانی است. این اثر با وجود نقطه ضعف خودکوچکبینی فرهنگی، به هر حال در گوشهای از طیف ادبیات علمی- تخیلی جای دارد و از این بابت جای خوشحالی است.
در ضمن تعدادی داستان کوتاه نیز اینجا و آنجا در مجلات چاپ شدهاند که متأسفانه به دلیل عدم دسترسی به منابع، از ذکر نام آنها خودداری میشود.

هنوز هیچیک از استادان محترم دانشگاهها حتی یک داستان کوتاه علمی- تخیلی به رشته تحریر درنیاوردهاند. حتی در رشتههای ادبیات فارسی یا انگلیسی نیز یک واحد به بررسی ادبیات علمی- تخیلی اختصاص نیافته است و این امر فقط دو دلیل میتواند داشته باشد: اول ناآگاهی یا بیتوجهی عمدی به این شاخۀ مهم ادبی و دوم به رسمیت-نشناختن این قالب داستانی. وضعیت در زمینه سینما و فیلمنامهنویسی که خود فرزندان ادبیات هستند، به همان اندازه تأسفانگیز و ناچیز است.
پ- سومین نقطه ضعف این شاخۀادبی نوعی غربزدگی ضعیف است که بیشتر از ذهنیت شرطیشده و عادتی خوانندگان و مترجمان و نویسندگان برمیخیزد.
متأسفانه علاقهمندان ایرانی به علت آنکه بیست سال رمانهای ترجمهای علمی- تخیلی خواندهاند یا فیلمهای علمی- تخیلی آمریکایی و اروپایی تماشا کردهاند و چون در اینگونه داستانها پیوسته با اسامی فرنگی اشخاص و شهرها، دستگاهها و اصطلاحات روبهرو بودهاند، به سختی میتوانند داستانی با اسامی و اصطلاحات ایرانی را بخوانند و علمی- تخیلیبودن آن را بپذیرند.
این نقطه ضعف حتی در میان ناشران، منتقدان و حتی بعضی نویسندگان نیز مشاهده میشود. برای مثال در کتاب «آخرین بنیاد کهکشان» نویسنده نهتنها به خوانندۀ عادی اجازه نمیدهد آنچه را که تألیف کرده از داستانهای ترجمهای تشخیص دهد بلکه در داستانها از اسامی غربی نیز استفاده کرده است. چرا؟ مگر ایرانی نمیتواند دانشمند باشد؟ یا روزی به فضا دست یابد؟ یا روزی دوباره جایگاه علمی خود را در جهان باز یابد؟ مگر در آمریکا همین ادبیات علمی- تخیلی نبوده است که دو نسل را به سوی علم و تحقیق جذب کرد و به دانشمندانی برجسته تبدیل کرد؟ چرا تعداد زیادی از دانشمندان آنها پیش یا پس از بازنشستگی، به نوشتن داستانهای علمی- تخیلی میپردازند؟
خوشبختانه زمینه برای زدودن این تصور اشتباه از ذهن خوانندگان و علاقهمندان به داستانهای علمی- تخیلی فراهم شده است و این امر فینفسه قدمی به پیش است.
به تناسب وضعیت بد بازار کتاب در ایران، انتشار گاه و بیگاه بعضی از کتابهای علمی-تخیلی در ایران، هرگز نتوانسته است جایگاه این ژانر ادبی را به سالهای طلایی دهه ۶۰ و اوایل دهه ۷۰ برگرداند.
معمولا ناشران و مترجمان در این سالها بسیار کمجرأت ظاهر شدهاند و شهامت آن را نداشتهاند که به جز نویسندگانی مثل آسیموف، سی کلارک، ری بردبری، به سراغ ترجمه داستانهای دیگران بروند یا مجموعه داستانهای منتخب گلچین کنند و منتشر کنند.
خوشبختانه دنیای اینترنت تا حدی عطش دوستداران علمی تخیلی را برطرف کرده است، مثلا مجله اینترنتی شگفتزار، شاید تنها مجلهای باشد که هماینک در اختیار داریم.

میزان دانلود بالای کتابهای علمی -تخیلی در سایتهای دانلود کتاب نشان میدهد که جوانان و نیاز میانسالانی علاقهمند به علمی- تخیلی کم نیستند.
بیشک ترجمه یا تألیف، روندی نیست که بخواهد بیمزد ادامه پیدا کند، شاید نشر و فروش الکترونیکی داستانهای علمی- تخیلی بتواند جوابگوی این نیاز باشد.
در پایان جهت تجدید خاطره نگاهی میاندازیم به روجلدهای تعدادی از رمانهای علمی تخیلی ترجمهشده در ایران در سالهای دور و نیز سالهای اخیر:










































فید یک پزشک محل مناسبی برای تبلیغات شما: محل تبلیغات متنی و بنری شما