Javascript基础回顾之(一) 类型

本来是要继续由浅入深表达式系列最后一篇的,但是最近团队突然就忙起来了,从来没有过的忙!不过喜欢表达式的朋友请放心,已经在写了:) 在工作当中发现大家对Javascript的一些基本原理普遍存在这里或者那里的一知半解,所以决定先花一些时间整理一下这些基础知识和大家分享。 刚开始是打算写一篇的,但是后来写着写着就发现越来越多,所以决定还是写一个系列吧。本系列所有内容都是涉及Javascript基础的,没有时髦的玩意儿,但是我相信这些基础的东西会有助于你理解那些有趣的东西的。

  • Javascript基础回顾之(一) 类型
  • Javascript基础回顾 (二) 作用域
  • Javascript基础回顾之(三) 面向对象

  是的,说到Javascript我能想到的就是有趣,好玩!那么到底哪些地方好玩,为什么好玩呢?我们一起来玩玩吧,让我们玩着玩着就把Javascript理解透彻了。本文所包括的内容:

基本类型
Object 与 object
基本包装类型
值类型和引用类型
function类型

基本类型
  Javascript有5种基本数据类型(也叫简单数据类型):Undefined、Null、Boolean、Number、String 和1种复杂数据类型Object。

var undefinedVariable;
var nullValue = null;
var cnblogs = new Object();
var func = function () { };

typeof ("string");
typeof (100);
typeof (true);
typeof (undefinedVariable);
typeof (cnblogs);
typeof (undeclaredValue);
typeof (nullValue);
typeof (null)
typeof (func)

告诉我结果是什么?

Javascript基础回顾之(一) 类型

  Javascript基础回顾之(一) 类型

好玩之一: 声明但未赋值 和 未声明的变量都是 undefined
好玩之二: 只有声明并赋值为null,它的值才会null
好玩之三: typeof(Object) 竟然是一个function
好玩之四: typeof(null) 竟然是一个object

  Null 和Undefined这两种类型都只有一个值,即null和undefined。从逻辑上看null值表示一个空对象的指针,这就是为什么typeof(null)会返回Object。 并且undefined是派生自null值的,所以......

好玩之五: null == undefined 是成立的。

  但是想一想,Null和Undefined毕竟是两种不同的类型,即使他们是父类和子类的关系,在C#里面父类和子类也不能相等啊,不是么?其实null == undefined就是硬性规定,ECMA规定它们做相等性测试的时候要返回true所以他们返回true了。就好像我们在C#里面重写了equlas 方法一样。

  至于为什么 typeof(Object) 返回 function,请看下面的Object与object。

Object 与 object
  Javascript高级程序一书中说到 ”函数在ECMAScript中是对象,不是一种数据类型”。 好像是译者加上去的,既然typeof(Object) 都返回 function了,为什么还说function不是一种数据类型呢?Object 和 function之间是什么关系呢?

  在我看来,Object其实就是一个function,或者我们说Object是一个函数的名字比较容易理解,官方名称是构造函数。

var p = new Object();
p.name = "jesse";
p.age = 18;

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

var p2 = new Person("jesse", 18);

在上面的代码中, 如果我们把Object当作一个函数名那么 new Object() 和 new Person() 性质就是一样的了。通过 new 操作符得到一个 function 实例, 这里面的function就已经是类的概念了。所以这里的Object其实是一个function。这样我们就可以解释为什么typeof(Object)是function了。

  那我们在上面所说的复杂类型Object,它又是什么呢?

Javascript基础回顾之(一) 类型

Object是function,但是 new Object() 则是 object。到这里面就搞清楚了首字母大写的这个Object是一个function,而首字母小写的这个object它才是一种数据类型。所以我建议大家以后说到类型的时候全部用小写,我们的基本类型是 string, number, boolean。大写的String, Number, Boolean 它们只是一个函数而已。而调用这些函数所得到的结果是,没错,是object。

Javascript基础回顾之(一) 类型

  最后,我们是找不到Undefined 和Null 这两个函数的,所以这两种数据类型就是undefined和null(为什么typeof(null)会得到object已经说了)

  Javascript基础回顾之(一) 类型

好玩之六: Object 不是object类型

基本包装类型
  我们上面讲了string, number, boolean是基本类型,基本类型和复杂类型最大的区别就是基本类型没有prototype属性。也就意味着你不能给基本类型随意的添加方法或属性。

var str = "str"; // typeof(str): string
var strObj = new String("str"); // typeof(strObj):object

strObj.name = "strObj";
strObj.alert = function () {
 alert(this.name);
};
strObj.alert(); // strObj

str.name = "str"; //wrong...
str.alert = function () {
 alert(this);
}
str.alert(); // this is wrong.... nothing is gonna happen.

同时我们还说到了首字母大写的这个String是一个function,所以new String("str")得到的是一个object而不是一个string,这里大家要搞清楚了。我们的问题来了,为什么基本类型string会有一些初始的方法呢?它不是基本类型么?方法是怎么加上去的?

str = str.concat("str2");
strObj = strObj.concat("str2");
strObj.alert(); //之后返回 string 不再是一个对象了, 所以这里也不再有alert方法了。

str是string类型的变量,记住它不是一个对象。它是不应该有方法的,那么它的contact方法从何而来呢?这里后台在调用str.contact的时候实际上偷偷的完成了几步操作:

  • 基于str创建一个String类型的实例
  • 在实例上调用指定的方法
  • 销毁这个实例

  将这三个步骤想象成这样:

var str2 = new String(str);
str = str2.concat("str2");
str2= null;

我们可以把String,Number,Boolean叫做封装类型, 他们就好像我们在C#里面的自定义类型一样。 但是不要忘记了我们真正的基本类型是string, number, boolean。用String所构造出来的对象是属于object类型的。

好玩之七: String 不是 string
值类型和引用类型
  我们上面讲到了5种基本类型:string, number, boolean, null, undefined 全部是值类型。Javascript中只有一种引用类型,也就是我们的复杂类型object。那么有人可能会好奇,那么像Date, Regex, Arrary这些是什么类型呢 ? 其实这里面的概念有一点混淆,如果你很好的理解了上面的Object 和object之间的区别,可能会比较好理解一点。 我们可以把function 看成是C#里面 class关键字,我们可以用class定义类,同样我们可以在Javascript中用function来定义类。

在C#中定义类:

namespace ConsoleApplication1
{
class Person
{
 public string Name { get; set; }

 public int Age { get; set; }
}

class Program
{
 static void Main(string[] args)
 {
 var p =new Person();
 Console.WriteLine(p.GetType()); // ConsoleApplication1.Person

 Console.ReadLine();
 }
}
}

在Javascript定义类:

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

var p = new Person();
typeof(p); //object

你发现区别了么?如果我们在Javascript中用function定义类,他们的实例将永远是object, 包括原生的那些Date, Array, RegExp。

typeof (new Date()); // object
typeof (new Array()); // object
typeof (new RegExp()); // object

Javascript基础回顾之(一) 类型

好玩之八: 全部都是object
  如果全部都是object的话,那我怎么能知道这个对象到底是不是Date或者Person的实例呢?借助于instanceof 就可以了。

Javascript基础回顾之(一) 类型

终级好玩:我用function创建了一个Person类,然后用new得到一个Person的实例,结果它却不是Person类型的。 这就好像生了个孩子,供他吃穿,但是他却不跟你姓,这得有多么无私伟大才干得出来的事啊!
function类型
  function类型有两种,函数声明和函数表达式。函数声明具有优先级,可以在声明之前被使用,表达式却不能。

sayGoodNight(); // right
sayHello(); // wrong

var sayHello = function (name) {
 alert("Hello, " + name);
};

function sayGoodNight(Name) {
 alert("Good Night, "+ name);
}

除此之外,函数表达式还可以像object一样,随意的添加属性。

var sayHello = function (name) {
 alert("Hello, " + name);
};

sayHello.age = 18;
sayHello.sayAge = function () {
 alert("I am" + 18) ;
}
sayHello.sayAge(); // I am 18

但是,函数表达式到底是个什么玩意儿呢? 不能实例化,但是可以随意的添加属性,它和object有什么区别?我们在上面说过,object其实就是一个对象实例。

我们还有大写的Function, 它和function之间的关系会不会和String 和string 一样?( 以下内容比较费脑力,慎入!)

var sayHello = new Function('name','alert("My name is " + name );');
sayHello('Jesse');
sayHello instanceof Function; // true

var sayHello2 = function (name) {
 alert('My name is' + name);
};
sayHello2 instanceof Function; // true

我们上面调用Function去构造了一个函数。既没有用函数声明,也没有用函数表达式,不管怎么说这是第三种创建函数的方法,虽然肯定没有多少人用它,因为它不管是参数,还是函数体全部都是字符串,这写起来还不让人崩溃么?

Javascript基础回顾之(一) 类型

  Javascript基础回顾之(一) 类型

看出什么猫腻来了么?所谓的函数表达式,其实是用一个变量接收了一个function的对象而已。而这个function的对象则是Function的实例。包括用函数声明写出来的函数也是Function的实例。

function sayHello3(name)
{
 alert('My name is' + name);
}
sayHello3 instanceof Function; // true

但是,等等,我们前面说到的String, Date, Array都是function类型的,那Function也是么?

Javascript基础回顾之(一) 类型

我们前面说所有function的实例都是object类型的,但是对于Function 这个奇异的function来说,它的实例仍然是function类型的,并且我们可以用Function的实例再创造实例。原来我们所说的用function创造出来的类,它不是类,而是Function的实例。

function Person(name) {
 this.name = name;
}
Person instanceof Function; // true

我们再结合自执行函数理解一下,也许会好一点:

(function () {
 alert("something...");
}());

实际上我们上面的function(){} 会返回给我们一个function的实例,那么我们当然可以直接执行它了。这么看来function应该是Javascript里面最特别的类型了。

好玩之十:所有的function都是Function的实例
好玩之十一:Function 本身也是一个function

Javascript基础回顾之(一) 类型

最后我们来总结一下:

  • Javascript中有5种基本类型:string, number, boolean, null, undefined。
  • 另外一种复杂类型object 其实是function的实例。
  • 除了Function这个系统里面的function构造器以外,其它所有function的实例都是object类型的。
  • Date, Array, RegExp 这些都是function类型,同时也是Function的实例。同理,它们的实例也是object类型的。

总结完了,好像也不多,不是么?关于function其实javascript是非常强大的一个功能,作用域以及面向对象的一些知识也是和它息息相关的,我们下一篇就来看看作用域的问题。谢谢大家的关注!

时间: 2017-01-30

理解javascript中的Function.prototype.bind的方法

在初学Javascript时,我们也许不需要担心函数绑定的问题,但是当我们需要在另一个函数中保持上下文对象this时,就会遇到相应的问题了,我见过很多人处理这种问题都是先将this赋值给一个变量(比如self._this.that等),尤其是var that = this是我见的最多的,这样当你改变环境之后就可以使用它.这些都是可以的,但是还有一种更好的.更专有的方法,那就是使用Function.prototype.bind,下面进行详尽的讲解. 第一部分:需要解决的问题 首先看下面的代码 va

javascript判断回文数详解及实现代码

javascript判断回文数 概要: 回文"是指正读反读都能读通的句子,它是古今中外都有的一种修辞方式和文字游戏,如"我为人人,人人为我"等.在数学中也有这样一类数字有这样的特征,成为回文数(palindrome number). 设n是一任意自然数.若将n的各位数字反向排列所得自然数n1与n相等,则称n为一回文数.例如,若n=1234321,则称n为一回文数:但若n=1234567,则n不是回文数. 注意: 1.偶数个的数字也有回文数124421     2.小数没有回文

JavaScript基础之AJAX简单的小demo

AJAX AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML). AJAX 不是新的编程语言,而是一种使用现有标准的新方法. AJAX 是与服务器交换数据并更新部分网页的艺术,在不重新加载整个页面的情况下. function prepareForms() { for(var j=0 ; j<document.forms.length ; j++){ var this_forms = document.forms[j]; rese

Javascript中的 “&” 和 “|” 详解

一.前言: 在文章开始之前,先出几个题目给大家看看: var num1 = 1 & 0; console.log(num1); // 0 var num2 = 'string' & 1; console.log(num2); // 0 var num3 = true & 1; console.log(num3); // 1 var num4 = undefined | false; console.log(num4); // 0 var num5 = undefined | tru

JavaScript实现时钟滴答声效果

下面一段代码给大家分享js实现时钟滴答声功能,具体代码如下所示: <!DOCTYPE html> <html> <head> <meta charset="utf8"> <meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1"> <meta name="keywords" content=&qu

Javascript基础回顾之(三) js面向对象

本来是要继续由浅入深表达式系列最后一篇的,但是最近团队突然就忙起来了,从来没有过的忙!不过喜欢表达式的朋友请放心,已经在写了:) 在工作当中发现大家对Javascript的一些基本原理普遍存在这里或者那里的一知半解,所以决定先花一些时间整理一下这些基础知识和大家分享. 后面会附上培训用的PPT.刚开始是打算写一篇的,但是后来写着写着就发现越来越多,所以决定还是写一个系列吧.本系列所有内容都是涉及Javascript基础的,没有时髦的玩意儿,但是我相信这些基础的东西会有助于你理解那些有趣的东西的.

浅谈javascript中的 “ && ” 和 “ || ”

有时候,我们会在jQuery框架或者其他js插件中发现里面有很多 " && " 和 " || ",那么这两个标识到底是什么含义?怎么使用?我觉得还是有必要稍微深究一下. 一.原理: && 操作符特点:逻辑运算表达式中只要一个是false就取false的值,都是true取后面,都是false取前面. || 操作符特点:逻辑运算表达式中只要一个是true就取true的值,都是true取前面,都是false取后面. 在js逻辑运算中,我们知

JavaScript Date 知识浅析

Date函数 new Date() Date 对象会自动把当前日期和时间保存为其初始值. date.getDate() 从 Date 对象返回一个月中的某一天 (1 ~ 31). date.getDay() 从 Date 对象返回一周中的某一天 (0 ~ 6).周日是0. date.getMonth() 从 Date 对象返回月份 (0 ~ 11). date.getFullYear() 从 Date 对象以四位数字返回年份 date.getHours() 返回 Date 对象的小时 (0 ~

Javascript中 带名 匿名 箭头函数的重要区别(推荐)

带名函数是指函数显示地给出了一个名字的函数,function abs(x){}.匿名函数是指函数只带有function这个关键字,而没有像abs这种函数名称的函数,如function(){}.ES6标准新增了一种新的函数:Arrow Function(箭头函数)箭头函数表面上相当于匿名函数,并且简化了函数定义.它们各自的区别是什么呢? 1 带名和匿名函数的区别 区别:匿名函数需要讲地址赋值给另一个变量let a,然后再用a来调用函数:而带名函数因为显示地给出了函数名称,所以可以直接用这个函数名称

Javascript中数组去重与拍平的方法示例

数组的判断 在说如何进行数组的去重和拍平之前,先说一下怎么判断数组,因为要进行数组的处理当然要先判断下传过来的数据是不是数组. 首先我们都知道js的数据类型只有5种,分别是Undefined.Null.Boolean.Number和String,数组只是一个对象,用typeof([])返回的结果知识一个Object的字符串,因此我们需要通过其他手段来判断它,这里就说两种方法. 第一种用instenceof方法 instanceof是ES5提供的一个方法,它可以用来判断实例是否是某个类的实例,例如

JavaScript数组复制详解

前面的话   前面的博文中介绍了对象拷贝,本文将详细介绍数组复制 push function copyArray(arr){ var result = []; for(var i = 0; i < arr.length; i++){ result.push(arr[i]); } return result; } var obj1=[1,2,3]; var obj2=copyArray(obj1); console.log(obj1); //[1,2,3] console.log(obj2); /

javascript 数组操作详解

1.数组的创建 var arrayObj = new Array(); //创建一个数组 var arrayObj = new Array([size]); //创建一个数组并指定长度,注意不是上限,是长度 var arrayObj = new Array([element0[, element1[, ...[, elementN]]]]); 创建一个数组并赋值 要说明的是,虽然第二种方法创建数组指定了长度,但实际上所有情况下数组都是变长的,也就是说即使指定了长度为5,仍然可以将元素存储在规定长

JavaScript数组操作详解

1.数组的创建 var arrayObj = new Array(); //创建一个数组 var arrayObj = new Array([size]); //创建一个数组并指定长度,注意不是上限,是长度 var arrayObj = new Array([element0[, element1[, ...[, elementN]]]]); //创建一个数组并赋值 要说明的是,虽然第二种方法创建数组指定了长度,但实际上所有情况下数组都是变长的,也就是说即使指定了长度为5,仍然可以将元素存储在规

javascript中Array()数组函数详解

在程序语言中数组的重要性不言而喻,JavaScript中数组也是最常使用的对象之一,数组是值的有序集合,由于弱类型的原因,JavaScript中数组十分灵活.强大,不像是Java等强类型高级语言数组只能存放同一类型或其子类型元素,JavaScript在同一个数组中可以存放多种类型的元素,而且是长度也是可以动态调整的,可以随着数据增加或减少自动对数组长度做更改. Array()是一个用来构建数组的内建构造器函数.数组主要由如下三种创建方式: array = new Array() array =

Javascript字符串常用方法详解

字符串 字符串就是一个或多个排列在一起的字符,放在单引号或双引号之中. 'abc' "abc" length属性 js里的字符串类似于数组,都是一个一个字符拼凑在一起组成的,因此可以用length属性取得字符串的长度 var str = "hello" str.length; // 5 字符串常用的一些方法 1. charAt() str.charAt(n) => 返回字符串的第 n 个字符,如果不在 0~str.length-1之间,则返回一个空字符串. v

jQuery数组处理详解(含实例演示)

1. $.each(array, [callback]) 遍历[常用] 解释: 不同于例遍 jQuery 对象的 $().each() 方法,此方法可用于例遍任何对象(不仅仅是数组哦~). 回调函数拥有两个参数:第一个为对象的成员或数组的索引, 第二个为对应变量或内容. 如果需要退出 each 循环可使回调函数返回 false, 其它返回值将被忽略. each遍历,相信都不陌生,在平常的事件处理中,是for循环的变体,但比for循环强大.在数组中,它可以轻松的攻取数组索引及对应的值.例: 复制代

javascript 面向对象function详解及实例代码

javascript 面向对象function详解     js中的函数有三种表示方式: //函数的第一种表示方式:函数关键字的方式 function f1() { alert("f1"); } //函数的第二种表示方式:函数字面量的方式 var f2 = function() { alert("f2"); } //函数的第三种表示方式:构造函数的方式 var f3 = new Function('var a = 100; b = 200; return a+b;'

Kotlin 语言中调用 JavaScript 方法实例详解

Kotlin 语言中调用 JavaScript 方法实例详解 Kotlin 已被设计为能够与 Java 平台轻松互操作.它将 Java 类视为 Kotlin 类,并且 Java 也将 Kotlin 类视为 Java 类.但是,JavaScript 是一种动态类型语言,这意味着它不会在编译期检查类型.你可以通过动态类型在 Kotlin 中自由地与 JavaScript 交流,但是如果你想要 Kotlin 类型系统的全部威力 ,你可以为 JavaScript 库创建 Kotlin 头文件. 内联 J

JavaScript作用域示例详解

作用域是JavaScript最重要的概念之一,想要学好JavaScript就需要理解JavaScript作用域和作用域链的工作原理.今天这篇文章对JavaScript作用域示例详解的介绍,希望能帮助大家更好的学习JavaScript. 任何程序设计语言都有作用域的概念,简单的说,作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期.在JavaScript中,变量的作用域有全局作用域和局部作用域两种. 一.JavaScript中无块级作用域 在Java或C#中存在块级作用域

C语言 指针与数组的详解及区别

C语言 指针与数组的详解及对比 通俗理解数组指针和指针数组 数组指针: eg:int( *arr)[10]; 数组指针通俗理解就是这个数组作为指针,指向某一个变量. 指针数组: eg:int*arr[10]; 指针数组简言之就是存放指针的数组: --数组并非指针&&指针并非数组 (1)定义一个外部变量: eg:int value=10; int *p=&value; 举例:当需要在一个函数中用这个变量时:externa int*p;而非extern int p[]; 分析:当用:e