2020-01-20

JavaScript 函数定义

JavaScript 使用关键字 function 定义函数。

函数可以通过声明定义,也可以是一个表达式。

函数声明

function functionName(parameters) {

  执行的代码

}

函数声明后不会立即执行,会在我们需要的时候调用到。

实例

function myFunction(a, b) {

    return a * b;

}

分号是用来分隔可执行JavaScript语句。

由于函数声明不是一个可执行语句,所以不以分号结束。

函数表达式

JavaScript 函数可以通过一个表达式定义。

函数表达式可以存储在变量中:

实例

var x = function (a, b) {return a * b};

在函数表达式存储在变量后,变量也可作为一个函数使用:

实例

var x = function (a, b) {return a * b};

var z = x(4, 3)

以上函数实际上是一个 匿名函数 (函数没有名称)。

函数存储在变量中,不需要函数名称,通常通过变量名来调用。

上述函数以分号结尾,因为它是一个执行语句。

Function() 构造函数

在以上实例中,我们了解到函数通过关键字 function 定义。

函数同样可以通过内置的 JavaScript 函数构造器(Function())定义。

实例

var myFunction = new Function("a", "b", "return a * b");

var x = myFunction(4, 3);

实际上,不必使用构造函数。上面实例可以写成:

实例

var myFunction = function (a, b) {return a * b};

var x = myFunction(4, 3);

在 JavaScript 中,很多时候,需要避免使用 new 关键字。

函数提升(Hoisting)

提升(Hoisting)是 JavaScript 默认将当前作用域提升到前面去的的行为。

提升(Hoisting)应用在变量的声明与函数的声明。

因此,函数可以在声明之前调用:

myFunction(5);

function myFunction(y) {

    return y * y;

}

使用表达式定义函数时无法提升。

自调用函数

函数表达式可以 "自调用"。

自调用表达式会自动调用。

如果表达式后面紧跟 () ,则会自动调用。

不能自调用声明的函数。

通过添加括号,来说明它是一个函数表达式:

实例

(function () {

    var x = "Hello!!";      // 我将调用自己

})();

以上函数实际上是一个 匿名自我调用的函数 (没有函数名)。

函数可作为一个值使用

JavaScript 函数作为一个值使用:

function myFunction(a, b) {

    return a * b;

}

var x = myFunction(4, 3);

JavaScript 函数可作为表达式使用:

实例

function myFunction(a, b) {

    return a * b;

}

var x = myFunction(4, 3) * 2;

函数是对象

在 JavaScript 中使用 typeof 操作符判断函数类型将返回 "function" 。

但是JavaScript 函数描述为一个对象更加准确。

JavaScript 函数有 属性 和 方法。

arguments.length 属性返回函数调用过程接收到的参数个数:

实例

function myFunction(a, b) {

    return arguments.length;

}

toString() 方法将函数作为一个字符串返回:

实例

function myFunction(a, b) {

    return a * b;

}

var txt = myFunction.toString();

函数定义作为对象的属性,称之为对象方法。

函数如果用于创建新的对象,称之为对象的构造函数。

箭头函数

ES6 新增了箭头函数。

箭头函数表达式的语法比普通函数表达式更简洁。

(参数1, 参数2, …, 参数N) => { 函数声明 }

(参数1, 参数2, …, 参数N) => 表达式(单一)

// 相当于:(参数1, 参数2, …, 参数N) =>{ return 表达式; }

当只有一个参数时,圆括号是可选的:

(单一参数) => {函数声明}

单一参数 => {函数声明}

没有参数的函数应该写成一对圆括号:

() => {函数声明}

实例

// ES5

var x = function(x, y) {

    return x * y;

}

// ES6

const x = (x, y) => x * y;

有的箭头函数都没有自己的 this。 不适合顶一个 对象的方法。

当我们使用箭头函数的时候,箭头函数会默认帮我们绑定外层 this 的值,所以在箭头函数中 this 的值和外层的 this 是一样的。

箭头函数是不能提升的,所以需要在使用之前定义。

使用 const 比使用 var 更安全,因为函数表达式始终是一个常量。

如果函数部分只是一个语句,则可以省略 return 关键字和大括号 {},这样做是一个比较好的习惯:

实例

const x = (x, y) => { return x * y }

this:

首先要知道this的是在代码执行的时候才能确定的,定义的时候不能确定,因为this是执行上下文的一部分,而执行上下文是在代执行的时候才能8定的。实际上this的最终指向的是那个调用它的对象。想理解this先看几个例子:

var a = {

name:'A',

fn: funcrion(){

console.log(this.name);

console.log(this);

}

}

a.fn();//this.name === 'A'; this===a

a.fn.call({name:'B'});//this.name===='B'; this==={name:'B'}

var fn1 = a.fn;

fn1();//this.name === undefined; this===window

通过上面的例子可以看出this的执行会有不同,主要集中在以下几种情况:1.作为构造函数执行,在构造函数中(上面例子未体现)2.作为对象属性执行,上述代码中的a.fn();3.作为普通函数执行,上述代码中fn1();4.用于call,apply,bind,上述代码中a.fn.call({name:'B'});

其中fn1() 的执行结果有些出乎意料,上文说过‘实际上this的最终指向的是那个调用它的对象’,fn1中this为什么指向了window?继续来看例子:

function a() {

var user = "例子";

console.log(this.user);//undefined

console.log(this);//window

}

a();

按照我们上面说的this最终指向的是调用它的对象,这里的函数a实际是被Window对象所点出来的,下面的代码就可以证明:

function a() {

var user = "例子";

console.log(this.user);//undefined

console.log(this);//window

}

window.a();

继续看例子:

var o = {

user: "例子",

fn: function(){

console.log(this.user);//'例子'

console.log(this);// o

}

}

o.fn(); ==>window.o.fn()

o.fn();等价于window.o.fn(),但是this并没有指向window,而是指向O对象;是不是有些迷惑,继续看例子:

var o = {

a = 10;

b : {

a:12;

fn:function(){

console.log(this.a);//12

console.log(this);//b

}

}

}

o.b.fn();

同样属性都是对象o调用出来的,但同样this没有指向O。其实我们需要知道以下几点:

1.如果一个函数中有this,但是没有被上一级对象调用,那么this就指向window,严格模式下t'his将指向undefined;2.如果一个函数中有this,这个函数被上一级对象调用,那么this指向上一级对象;3.如果函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也是其上一级对象。(上面的例子中,将b对象的值注销既可以验证)

var o = {

a = 10;

b : {

//a:12;

fn:function(){

console.log(this.a);//undefined

console.log(this);//b

}

}

}

o.b.fn();

还有个特殊的例子:

var o = {

a = 10;

b : {

a:12;

fn:function(){

console.log(this.a);//undefined

console.log(this);//window;

}

}

}

var c = o.b.fn;

c();

this指向的是最后调用它的对象,也就是看它执行的时候是谁调用的,这个例子中虽然函数fn是被对象b所引用,但是在将fn赋值给变量c的时候并没有执行所以最终指向的是window。

在构造函数中this指向也会不同:

function Fn(){

this.user = '例子';

}

var a = new Fn();

console.log(a.user)//'例子'

这里a可以调用到user的值,因为构造函数new关键字改变了this的指向,所以将this指向a。

当this遇到return时结果也会有差异,如下面的连个例子:

function Fn(){

this.user = '例子';

return {};

}

var a = new Fn();

console.log(a.user)//undefined

function Fn(){

this.user = '例子';

return 1;

}

var a = new Fn();

console.log(a.user)//'例子'

#####总结: 如果返回值是一个对象,那么this指向返回的这个对象,如果返回值不是一个对象,那么this还是指向函数的实例;null也是一个对象,但是null比较特殊,返回值是null,this还是指向函数的实例。

css实现两栏布局的总结:

两栏布局(左侧宽度固定,右侧自适应),在学习的过程中总结了几种方法:

方法一:float+margin-left

HTML部分

<div class="left">

<h1>Left Side</h1>

<p>我是左侧栏</p>

</div>

<div class="right">

<h1>Right Side</h1>

<p>我是右侧栏</p>

</div>

CSS部分

{

/清除默认格式/

margin:0;

padding:0;

}

.left{

width:200px;

background-color:red;

float:left;

}

.right{

background-color:green;

margin-left:200px;//等于左边栏的宽度

}


方法二:absolute+margin-leftCSS部分

{

margin:0;

padding:0;

}

.left{

width:100px;

background-color:red;

position:absolute;

}

.right{

background-color:green;

margin-left:100px;

}

方法三:float+BFC为左侧元素设置浮动后,左侧元素会因为浮动盖在右侧元素上,因此要将右侧元素变成BFC,BFC是一个独立的区域,不会让BFC外的元素对其内部造成干扰。当右侧元素变成一个BFC时它的元素边界会发生变化,会紧紧贴合左侧的元素。常见的右侧元素设置----overflow:hidden;

方法四:flex布局HTML部分

<div class="box">

<div class="left">

<h1>Left Side</h1>

<p>我是左侧栏</p>

</div>

<div class="right">

<h1>Right Side</h1>

<p>我是右侧栏</p>

</div>

</div>

CSS设置:

{

/清除默认格式/

margin:0;

padding:0;

}

.box{

display:flex;

}

.box1{

}

.box2{

flex:1;

}

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

推荐阅读更多精彩内容

  • 单例模式 适用场景:可能会在场景中使用到对象,但只有一个实例,加载时并不主动创建,需要时才创建 最常见的单例模式,...
    Obeing阅读 2,050评论 1 10
  • "use strict";function _classCallCheck(e,t){if(!(e instanc...
    久些阅读 2,027评论 0 2
  • 一、你不知道的JavaScript 1、作用域 作用域 LHS RHS RHS查询与简单地查找某个变量的值别无二...
    顶儿响叮当阅读 343评论 0 0
  • 1、使用typeof bar ===“object”来确定bar是否是一个对象时有什么潜在的缺陷?这个陷阱如何避免...
    深海鲫鱼堡阅读 655评论 1 1
  • https://www.zcfy.cc/article/37-essential-javascript-inter...
    小明yz阅读 415评论 0 2