JavaScript语言的特点
0 44

JavaScript是一门非常简练并且功能强大的脚本语言,其机制和原理具有非常与众不同的特点。

 一切都是对象

JavaScript中,数值、字符串、数组、函数等一切都属于对象(Object)。

与其他语言一样,JavaScript仍然支持如下所示的原始数据类型及相应的字面量定义方式:

  • 数值型 如:3、-2、3.14
  • 字符串型 如:“Hi,world!”、“china”
  • 布尔型 如:true、false

但与一般语言不同的是,基于一切都是对象的思想,JavaScript语言引擎会在程序执行时对以上原始数据类型自动创建相应的包装对象,从而可以象对象一样调用其对象方法。

  • 数值型 –> Number
  • 字符串型–> String
  • 布尔型–> Boolean

例如,String对象都拥有返回字符串长度的length属性,如果访问“Hi,world!”.length、 将获得返回值9。

而且,JavaScript的对象模型非常简单,JavaScript中的对象就是个键/值对的集合。

这里的「键」不限于字符串类型,也可以是数值或其他对象。

事实上,JavaScript中的数组(Array),本质上也是一个键/值对的集合,自然索引也是作为属性名(键)存在的。

对象基于原型

Java或C++等基于类的面向对象语言都包含有两个基本概念:类(Class)和实例(Instance)。类是一个抽象的模板,比如Employee类,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可能不同。

而JavaScript的面向对象的基本概念是原型(Prototype)。对象不分类和实例,但对象可以将其他的对象作为自己的原型,然后根据需要定义独自的属性。

运行期,JavaScript语言引擎会为所有的对象维护一个原型链,原型链的顶端是Object对象。

当对象被访问属性时,语言引擎会先查找对象本身,对象本身不存在该属性时,然后按照原型链从下到上依次查找。这就是JavaScript语言中的继承机制。

ECMAScript6虽然也引入了类(Class),但这并不意味着JavaScript在原型机制之外导入了一个类似于C++「类」的新机制。

ECMAScript6中的类仅仅是提供了一个更简单明了的语法方法用于定义构造函数,本质上就是构造函数,这也是其常常被说成是语法糖的缘由。

完全动态语言

JavaScript是一个完全动态的语言,这里包含以下三个意思:

  1. JavaScript是一个动态类型语言
  2. JavaScript是一个弱类型语言
  3. JavaScript是一个动态编程语言

其中,动态类型语言和动态编程语言是两个不同的概念,本身并没有关联性。

动态类型语言

动态类型语言(Dynamically Typed Language)指的是在运行期而不是在编译期对类型进行检查的一类语言。

  • 备注: 作为解释语言的JavaScript等语言,其编译期可以理解成将脚本加载并转换为内部可执行代码这样一个过程。

属于动态类型语言的还有PHP、Ruby、Python等。

与动态类型语言相对的就是静态类型语言(Statically Typed Language),C#、Java、TypeScript等就属于这类语言。

弱类型语言

弱类型语言具有以下特点:

  1. 变量没有类型,可以被赋予不同类型的值
  2. 计算时不同类型的值会自动进行转化

同属动态类型语言的PHP、Ruby、Python中,PHP、Ruby也属于弱类型语言,而Python因为变量在第一次被赋值后,其类型便已被确定下来,另外计算时必须强制指定类型转化,因此通常被认为是强类型语言。

动态编程语言

动态编程语言(Dynamic Programming Language)指的是能够在运行中动态改变其程序结构,包括增加新的函数、类型等的一类语言。 JavaScript里可以在函数里嵌套函数,如下例所示,嵌套函数f2就是在外面的f1()函数被调用时才创建的,这也是JavaScript闭包实现的基础。

function f1(x) {  
  function f2() {    
    return x;  
  }  
  return f2;
}
f1(3);

部分支持函数编程

JavaScript部分具有函数语言的特点,函数语言本身可能比较复杂,但对于JavaScript来说,您只要掌握以下3点就可以了:

  • 所有的函数都有返回值
  • 函数没有副作用
  • 函数也可以当作值进行处理

函数都有返回值

所有的函数都返回值,如果没有明确的代码实现,函数的返回值就是undefined。

函数没有副作用

函数没有副作用,包含以下两点:

  • 函数不应改变外部的变量值
  • 函数不应改变引用传递的参数的值

函数也是值

函数也是对象,一种可以被执行的特殊对象。 函数能够当作值进行处理,因此関数的参数可以是另外一个函数,函数的返回值也可以是一个函数。

闭包

闭包是函数式语言中一个非常重要和强大的功能。JavaScript在函数对象被创建时会把当时的执行环境保存起来,形成一个闭包作用域,函数每次执行时都能够访问这个作用域中的变量。因此,闭包通常用来创建内部变量,使得这些变量不能被外部随意修改,同时又可以通过指定的函数接口来操作。

0 44
() 全部评论
所有回复 (0)

热门

最新

  • Web3D编程 2 0 1 发布

    点击查看例子

    代码效果


    源码

    <!DOCTYPE html> <html> <head> <title>材质和光源</title> <script type="text/javascript" src="../libs/three.js"></script> <script type="text/javascript" src="../libs/stats.js"></script> <script type="text/javascript" src="../libs/dat.gui.js"></script> <style> body { /* set margin to 0 and overflow to hidden, to go fullscreen */ margin: 0; overflow: hidden; } </style> </head> <body> <!-- Div which will hold the Output --> <div id="LapBin-output"> </div> <!-- Javascript code that runs our Three.js examples --> <script type="text/javascript"> // 加载所有内容后,我们将运行Three.js function init() { // 创建一个场景,该场景将包含所有元素,例如对象、摄影机和灯光。 var scene = new THREE.Scene(); // 创建一个摄像头,它定义了我们要看的范围。 var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.2, 1000); // 创建渲染并设置大小 var renderer = new THREE.WebGLRenderer(); renderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0)); renderer.setSize(window.innerWidth, window.innerHeight); renderer.shadowMapEnabled = true; // 创建平面 var planeGeometry = new THREE.PlaneGeometry(60, 30); var planeMaterial = new THREE.MeshLambertMaterial({color: 0xffffff}); var plane = new THREE.Mesh(planeGeometry, planeMaterial); plane.receiveShadow = true; // 旋转并定位平面 plane.rotation.x = -0.5 * Math.PI; plane.position.x = 10; plane.position.y = 0; plane.position.z = -10; // 将平面添加到场景中 scene.add(plane); // 创建一个立方体 var cubeGeometry = new THREE.BoxGeometry(4, 4, 4); var cubeMaterial = new THREE.MeshLambertMaterial({color: 0xff0000}); var cube = new THREE.Mesh(cubeGeometry, cubeMaterial); cube.castShadow = true; // 定位立方体 cube.position.x = -4; cube.position.y = 3; cube.position.z = -10; // 将立方体添加到场景中 scene.add(cube); // 创建一个球体 var sphereGeometry = new THREE.SphereGeometry(4, 20, 20); var sphereMaterial = new THREE.MeshLambertMaterial({color: 0xdd77ff}); var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial); // 定位球体 sphere.position.x = 20; sphere.position.y = 4; sphere.position.z = -10; sphere.castShadow = true; // 将球体添加到场景中 scene.add(sphere); // 将摄影机定位并指向场景的中心 camera.position.x = -30; camera.position.y = 40; camera.position.z = 30; camera.lookAt(scene.position); // 为阴影添加聚光灯 var spotLight = new THREE.SpotLight(0xffffff); spotLight.position.set(-40, 60, -10); spotLight.castShadow = true; scene.add(spotLight); // 将渲染器的输出添加到html元素 document.getElementById("LapBin-output").appendChild(renderer.domElement); // 渲染场景 renderer.render(scene, camera); } window.onload = init; </script> </body> </html>
  • LapBin(ThreeJS) 6 0 1 发布
  • 点击查看例子

    代码效果




    天空盒使用源码

    <!DOCTYPE html> <html lang="en">     <head>         <title>three.js - skybox</title>         <meta charset="utf-8">         <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">         <link type="text/css" rel="stylesheet" href="main.css">     </head>     <body>         <div id="container"></div>         <script type="module">             import * as THREE from '../build/three.module.js';             import { OrbitControls } from './jsm/controls/OrbitControls.js';             var scene, camera , renderer;             init();             animate();             function init() {                 // scene                 scene = new THREE.Scene();                 // camera                 camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 200 );                 camera.position.set( - 15, 7, 15 );                 camera.lookAt( scene.position );                              // skybox                 var cubeTextureLoader = new THREE.CubeTextureLoader();                 cubeTextureLoader.setPath( 'textures/cube/Park2/' ); //天空盒图片文件路径                 var cubeTexture = new THREE.CubeTextureLoader.load( [                     "posx.jpg", "negx.jpg", //图片 http://www.cglap.com/assets/lapbin/textures/cube/Park2/negx.jpg                     "posy.jpg", "negy.jpg", // http://www.cglap.com/assets/lapbin/textures/cube/Park2/negy.jpg                     "posz.jpg", "negz.jpg" //http://www.cglap.com/assets/lapbin/textures/cube/Park2/negz.jpg                 ] );                 scene.background = cubeTexture;                 // light                 var ambientLight = new THREE.AmbientLight( 0xcccccc, 0.4 );                 scene.add( ambientLight );                 var directionalLight = new THREE.DirectionalLight( 0xffffff, 0.6 );                 directionalLight.position.set( - 1, 1, 1 );                 scene.add( directionalLight );                 // renderer                 renderer = new THREE.WebGLRenderer( { antialias: true } );                 renderer.setSize( window.innerWidth, window.innerHeight );                 renderer.setPixelRatio( window.devicePixelRatio );                 document.body.appendChild( renderer.domElement );                 // 鼠标控制旋转                 var controls = new OrbitControls( camera, renderer.domElement );                 controls.minDistance = 5;                 controls.maxDistance = 50;                              //                 window.addEventListener( 'resize', onResize, false );             }             function onResize() {                 camera.aspect = window.innerWidth / window.innerHeight;                 camera.updateProjectionMatrix();                 renderer.setSize( window.innerWidth, window.innerHeight );             }             function animate() {                 requestAnimationFrame( animate );                 render();             }             function render() {                 renderer.render( scene, camera );             }         </script> </body> </html>
  • 例子查看链接gui

    为了能够快速地搭建three.js的交互ui,官方提供了一个GUI组件,通过简单的语法学习就能够使用。

    下面我们就来学习如何使用

    用法一

    首先声明一个对象,这个对象设置获取一个交互.

       var params = {                 color: '#ffffff',                 scale: 4,                 flowX: 1,                 flowY: 1 , states:"Walking"             };

    然后就就可以使用GUI来进行生成交互UI组件

    生成一个panel组件版,然后将组件的对象添加到这个组件版,完成之后就能够生成一个交互界面了。

     // dat.gui

    颜色选择器                var gui = new GUI();                 gui.addColor( params, 'color' ).onChange( function ( value ) {                    // do something                 } );


    拉动条
    不仅可以生成按钮,也可以生成拉动条。 gui.add( params, 'scale', 1, 10 ).onChange( function ( value ) { // do something  } );


    gui.add( params, 'flowX', - 1, 1 ).step( 0.01 ).onChange( function ( value ) {                   // do something } );


     gui.add( params, 'flowY', - 1, 1 ).step( 0.01 ).onChange( function ( value ) {                   // do something                 } );


    下拉表
     //选项 var states = [ 'Idle', 'Walking', 'Running', 'Dance', 'Death', 'Sitting', 'Standing' ];  // 添加  gui.add( params, 'states' ).options( states ).onChange( function ( value ) {              // do something } );
    效果图


    全部代码

    <!DOCTYPE html> <html lang="en">     <head>         <title>three.js - gui</title>         <meta charset="utf-8">         <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">         <link type="text/css" rel="stylesheet" href="main.css">     </head>     <body>         <div id="container"></div>         <script type="module">             import * as THREE from '../build/three.module.js';             import { GUI } from './jsm/libs/dat.gui.module.js';             var scene, camera, renderer;             var params = {                 color: '#ffffff',                 scale: 4,                 flowX: 1,                 flowY: 1,                 states:"Walking"             };             init();             animate();             function init() {                 // scene                 scene = new THREE.Scene();                 // camera                 camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 200 );                 camera.position.set( - 15, 7, 15 );                 camera.lookAt( scene.position );                 // renderer                 renderer = new THREE.WebGLRenderer( { antialias: true } );                 renderer.setSize( window.innerWidth, window.innerHeight );                 renderer.setPixelRatio( window.devicePixelRatio );                 document.body.appendChild( renderer.domElement );                 // dat.gui                 var gui = new GUI();                 gui.addColor( params, 'color' ).onChange( function ( value ) {                     //do something                 } );                 gui.add( params, 'scale', 1, 10 ).onChange( function ( value ) {                     //do something                 } );                 gui.add( params, 'flowX', - 1, 1 ).step( 0.01 ).onChange( function ( value ) {                     //do something                 } );                 gui.add( params, 'flowY', - 1, 1 ).step( 0.01 ).onChange( function ( value ) {                     //do something                 } );                 //选项                 var states = [ 'Idle', 'Walking', 'Running', 'Dance', 'Death', 'Sitting', 'Standing' ];                  gui.add( params, 'states' ).options( states ).onChange( function ( value ) { //do something                 } );;                              gui.open();                 window.addEventListener( 'resize', onResize, false );             }             function onResize() {                 camera.aspect = window.innerWidth / window.innerHeight;                 camera.updateProjectionMatrix();                 renderer.setSize( window.innerWidth, window.innerHeight );             }             function animate() {                 requestAnimationFrame( animate );                 render();             }             function render() {                 renderer.render( scene, camera );             }         </script> </body> </html>
  • LapBin(ThreeJS) 12 0 1 发布