javascript基础语法学习

前言

这是一次简单的JavaScript基础语法的重新学习,只记录JavaScript与C\C++的不同之处,相同的不再赘述。

一、输出

  • 使用 window.alert() 弹出警告框。

  • 使用 document.write() 方法将内容写到 HTML 文档中。

  • 使用 innerHTML 写入到 HTML 元素。

  • 使用 console.log() 写入到浏览器的控制台。(常用)

二、变量

1.声明

  • var namevar num = 1。 不用说明变量的类型,编译器会自行判断。若初始化,则是初始化值的类型;若未初始化,则是undefined数据类型。每当该变量再次被赋值或再次被声明定义时,会被转换成新的数据类型。

  • let name。 声明的是块级作用域变量,只在块级作用域内有效,不能被块外部访问,且不可重名。块级指{....}之内的内容,如for{}中。

  • const name = 'jek'。 声明常量,块级作用域,必须初始化,不可修改。

后两种声明方式为ES6特性。

练习代码:

//----------var、let、const声明变量-------------
  // var声明变量后,赋不同类型的值和重新声明定义
  var v1 = 1;
  console.log(v1, typeof v1);
  v1 = 'ssss';
  console.log(v1, typeof v1);
  var v1 = false;
  console.log(v1, typeof v1);

  // 函数局部
  function myFunction() {
    // var局部变量,外部可访问,但不能访问到局部变量的值。按理来说局部是不可访问的,此处笔者也很迷惑
    var name = 'bbbb';  
  }
  console.log(name, typeof name);   // 输出 空字符 + string

  // 块级区域
  for (var i = 0; i < 5; i++) {
    var x = i;      // var声明块级变量,外部可以访问且值相同
  }
  console.log(x);

  for (var i = 0; i < 5; i++) {
    let y = i;      // let声明块级变量,外部不可访问
  }
  console.log(y);

输出结果:

1 "number"
ssss string
false "boolean"
 string
4
Uncaught ReferenceError: y is not defined

(注:js有变量提升的特性,即允许先使用(如赋值)再声明,但不建议使用)

2.数据类型(6种值类型+3种引用类型)/(6种原始类型+对象类型)

1)string

字符串:var str = 'hello'。 可以用双引号或单引号包裹,如"hello"'hello'都可以(建议用单引号)。可以通过下标访问字符串中的字符。

两个字符串之间可以通过 + 拼接。

ES6中新增了字符串模板的特性。字符串需用``包裹起来,字符串中需要替换的变量用${}包裹。示例:

var name="zzw";
console.log(`hello ${name}`);

输出hello zzw

2)number

数字:var num = 1。 包括整数、浮点数、科学计数法表示的数(2.1e10)。js中浮点数的精度是个问题。数字可以与字符串通过 + 拼接,此时数字会被转换成字符串。

3)boolean

布尔类型:var bo = true

4)undefined

无定义类型:var name。 变量声明时没有被定义,或者输出一个未声明的变量,则为undefined类型。

5)null

空类型:var name = nullname = null。 用来将变量置空,其实表示一个空对象引用。

6)symbol

symbol 是 ES6 引入了一种新的原始数据类型,表示独一无二的值。

7)array

数组:var arr = [1,2,3]或者var arr = new Array(1,2,3)。 在js中数组类型其实算作一种对象类型。 而且,js数组与C数组还有几个不同点:

  • js数组的每一项可以用来保存任何类型的数据,也就是说,可以用数组的第一个位置来保存字符串,第二个位置保存数值,第三个位置保存对象。
  • 数组的大小是可以动态调整的。
  • 访问超限时,输出undefined。
8)function

函数。在js中,函数也可以是变量,后面详细介绍。

9)object

对象。也算变量,后面再详细介绍。

练习代码:

//----------变量------------
  // number类型
  var num = 3;
  console.log(num, typeof num);

  // string类型
  var str = 'hello';
  console.log(str, typeof str);

  // 拼接字符串和数字
  console.log(str+' '+num);

  // boolean类型
  var bo = true;
  console.log(bo, typeof bo);

  // undefined类型
  var udf;
  console.log(udf, typeof udf);

  // null类型
  var nu = null;
  console.log(nu, typeof nu);

  // 数组
  var arr = [1,2,3];
  // var arr = new Array(1,2,3);
  console.log(arr, typeof arr);
  console.log(arr[9]);  // 访问超限,输出undefined
  arr = [1, 'hello', [2, 3]];
  console.log(arr, typeof arr);

  // 函数类型
  var fun = function() {
    console.log('this is a function');
  }
  console.log(fun, typeof fun);

  // 对象类型
  var obj = {
    name: 'tomcat',
    getName: function() {
      return name;
    }
  };
  console.log(obj, typeof obj);

输出结果:

3 "number"
hello string
hello 3
true "boolean"
undefined "undefined"
null "object"
[1, 2, 3] "object"
undefined
[1, "hello", Array(2)] "object"
ƒ () {
        console.log('this is a function');
    } "function"
{name: "tomcat", getName: ƒ} "object"

三、运算符

特别注意:在js中有相等==和绝对相等===,不相等!=和不绝对相等!==。区分如下:

  • ==。 值相等,类型可以不相等
  • ===。 值和类型都必须相等
  • !=。 ==取反,即类型相等时,值不相等
  • !==。 ===取反,即值或类型都可以不相等

其它运算符与c的相同。

四、语句

if、for、while、switch等,与c相同。

五、函数(重要)

1.函数定义

1)函数语句定义(常规)

参数,可有可无,不用指定数据类型(js中,变量本就不需指定类型),默认为undefined类型。传入参数个数不定,按顺序未传入的参数为undefined。ES6中参数可以设定默认值。

返回值,可有可无。

function funA (a, b) {
    console.log('a is ' + a);
    console.log('b is ' + b);
    console.log('a+b is ' + (a+b));
}
funA(2, 4);
funA(2);

// ES6 函数参数可以设定默认值
function funB (a, b = 10) {
    console.log('默认值 || ' + (a+b));
}
funB(3);

输出:

a is 2
b is 4
a+b is 6
a is 2
b is undefined
a+b is NaN
默认值 || 13
2)函数表达式(函数变量)定义

将匿名函数赋给一个变量,该变量可以跟函数一样使用,其数据类型为函数类型。

var vB = function (a, b) {
    return a*b;
};
vB(2, 3);

在《JavaScript权威指南》中说:

以表达式定义的函数只适用于它作为一个大的表达式的一部分。

其实,我觉得表达式定义形式也可以用于一般函数。感觉两者没什么太大区别,可能也是我不了解js的内部实现。

2.匿名函数

不带函数名的函数,即为匿名函数,如:

function () {
    console.log('this is an anonymous function');
}

可单单定义一个匿名函数是无法调用的,因为它没有名字。但,我们可以通过将匿名函数赋给变量(该变量成为函数类型变量),或函数自调用的方式,来调用匿名函数。

ES6新增用箭头函数来表示匿名函数:

// ES6 新增箭头函数来表示匿名函数,一个参数时可以省略圆括号,一条语句可以省略花括号
var vB = (a, b) => {
    console.log('箭头函数 || a-b is ' + (a-b));
};
vB(6, 3);

3.函数自调用

其形式为 (...匿名函数定义...)(...参数...); 。作用是在函数定义后立即调用该函数:

(function (a, b) {
    console.log('函数自调用 || a-b is ' + (a-b));
})(6, 2);

((a, b) => {
    console.log('箭头函数 || a-b is ' + (a-b));
})(6, 2);

输出:

函数自调用 || a-b is 4
箭头函数 || a-b is 4

4.函数作为值

在js中,函数也是变量,那么函数就可以当作一个变量来进行传递。

1)函数作为返回值(函数闭包)

函数返回一个子函数(嵌套函数),那接受这个返回值的变量即是函数类型变量。

function fa (first) {
    return function (second) {
        return first += second;
    };
}
var son = fa(0);    // son变量接受一个返回函数
/*相当于
var son = function (second) {
    return first += second
};
只是这样定义时,不能使用函数fa()的局部变量first
*/
console.log(son(1));    // 输出 1
console.log(son(1));    // 输出 2

function fa (first) {
    return (second) => {
        return first += second;
    };
}
var son = fa(0);
console.log(son(1));
console.log(son(1));

// 直接将fa函数写成自调用的匿名函数,自调用后返回一个函数给son变量
var son = (((first) => {
    return (second) => {
        return first += second;
    };
})(0));
console.log(son(1));
console.log(son(1));

输出:

1
2

从第一个代码示例中,我们可以发现:返回一个函数(fa)的内部函数(son)时,我们可以通过这个返回的函数(son)来使用外函数(fa)中的局部变量。而且在不断调用内部函数(son)的过程中,外函数(fa)并没有被销毁(出栈)。由于这种机制,我们就可以让函数拥有私有变量,不能被全局使用,但又可以一直保持值不被销毁。而这就是闭包

代码:

//函数闭包。使函数可以拥有私有变量(外部不可访问,同时也不会因为函数调用而刷新)
var add = (() => {
    var counter = 0;
    return () => {return counter += 1;}
})();
add();  // add()实际调用的是上述匿名主函数中返回的匿名子函数
add();
add();
console.log('函数闭包 || ', add());

输出:

函数闭包 ||  4
2)函数作为参数(多态性/Lambda表达式)

将一个自定义函数作为参数传入另一个函数中,这个传入函数可以根据不同情况自行定义,从而让被传入函数实现不同效果。

// 函数作为参数。使多态性得以体现
function appendDiv (callback) {
    for(var i=0;i<10;i++){
        var div = document.createElement('div');
        div.innerHTML = i;
        document.body.appendChild(div);
        // 如果传入的参数是一个函数类型的变量
        if(typeof callback == 'function'){
            callback(div);      // 将该形参作为函数变量使用
            console.log(callback);
        }
    }
}
// 将一个自定义的匿名函数作为参数传入appendDiv()函数
appendDiv((node) => {
    node.style.display='block';     // 让该元素以块元素展示(独占一行)
});
appendDiv((node) => {
    node.style.display='inline';    // 让该元素以行内元素展示
});

显示结果:


函数作为参数.png

函数作为参数传入另一个函数的方式,常用于将自定义的回调函数传入接口函数中。但,在传入自定义参数到接口函数的这种场景中,常常是将回调函数作为对象中的一个方法传入的。

如微信小程序开发中常用的网络请求接口函数:

wx.request({
  url: wx.getStorageSync('requestUrl') + '/small/config',
  method: 'GET',
  data: {
  },
  header: {
    'content-type': 'application/json'
  },
  success: (res) => {
    console.log('get config: ', res.data.WeCosUrl)
    wx.setStorageSync('wecosUrl', res.data.WeCosUrl)
  }
});

wx.request()是微信提供的用于网络请求的接口函数,其参数是一个对象。对象中的success方法,是wx.request()函数执行访问成功后调用的函数,由用户自定义。而这就是一种多态性。

六、对象(重要)

1.js中的对象

在js中,大部分事物都是一个对象。引用《JavaScript权威指南》中的话说:

除了字符串、数字、true、false、null和undefined之外,JavaScript中的值都是对象。尽管字符串、数组和布尔值不是对象,但它们的行为和不可变对象非常类似。

字符串有对象的部分特性,如:

var message='Hello World!';
console.log(message.length);    // 获取字符串的长度属性

但,字符串“对象”的属性是不可修改的,如修改message.length的大小是无效的。同时,字符串还有很多常用的自带方法,如:内容匹配match()、内容替换replace()、转换大小写toUpperCase()/toLowerCase()等等。

2.对象创建

js中,对象用{...}将属性和方法包裹起来。每个属性和方法都有唯一的名字,而且名字和值之间是通过:一一映射的。如:

var obj = {
  name: 'tomcat',
  getName: function() {
    return this.name;
  }
};
console.log(obj.getName()); // 输出 tomcat

this的注意点

this关键字指向的是调用该函数的对象。如果不使用this.name,可能会返回全局中的name变量。如:

var obj = {
  name: 'tomcat',
  getName: function() {
    return name;
  }
};
var name = 'tom';
console.log(obj.getName()); // 输出 tom

另外,箭头函数虽然是匿名函数的一种简写,但实际上,箭头函数和匿名函数有个明显的区别:this指针的指向。匿名函数中this指向调用者对象,而箭头函数中的this指向再上一层调用者对象。如:

var name = 'tom';
var obj = {
    name: 'tomcat',
    getName: () => {
        console.log(this);  // 输出 window对象
        // 由于箭头函数,this指针指向上一层对象,即全局对象,因此这里的this.name是全局中的name变量
        return this.name;   
    }
};
console.log(obj.getName()); // 输出 tom

所以,在对象的方法定义中,不建议使用箭头函数


对象还可以通过new + 构造函数的方法来创建,如:

var o = new Object(); // Object()是Object这个js“原型”对象的构造函数。返回一个空对象

3.js对象属性和方法的动态性

可以动态增加与删除对象中的属性和方法,如:

// 动态增加属性 方法
var book = {};
// var book = new Object();
book.author = 'es6';
book.title = 'JavaScript';
book.changeTitle = function () {
    this.title = 'python';
    return this.title;
};
console.log(book.author, book.title, book.changeTitle());   // 输出 es6 JavaScript python

// 删除属性、方法
delete book.author;
console.log(book.author); // 输出 undefined

4. js对象的引用与赋值

js中对象值是引用类型,相当于指针。

// 对象的引用与赋值
var obj1 = {
  a : 1
}
var obj2 = obj1;
obj2.a = 2;
console.log(obj1.a);  // 输出2

var obj2 = obj1;相当于把obj1的指针赋给obj2,所以obj1obj2指向同一对象的数据。

同时,若函数参数为对象,并在函数中修改对象中数据,那也会影响到函数外的对象。

那js应该如何正确的进行对象赋值呢,代码如下:

// 对象间赋值的正确方法
var obj3 = {
  a:1,
  b:2,
  c:3,
  d:[0,1,2,3]
};
var jsonStr = JSON.stringify(obj3);
var obj4 = JSON.parse(jsonStr);
obj4["e"] = 4;
obj4["d"][0] = 11;
console.log(obj3);  //Object {a: 1, b: 2, c: 3, d: [0,1,2,3]}
console.log(obj4);  //Object {a: 1, b: 2, c: 3, d: [11,1,2,3], e: 4}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容