我在原型函数中得到一个未定义的符号。我向console.log写了'this'和'self'值。值从第一次调用通过直接调用变为后来的调用,通过'zoom'回调。我有一个jsfiddle,http://jsfiddle.net/eric_l/kQSTH/,打开控制台将允许人们看到错误消息。既不是“这个”也不是“自我”的任何想法都能正常运作?
<!DOCTYPE html>
<meta charset="utf-8">
<title>Zoom by Rectangle</title>
<script src="http://d3js.org/d3.v3.min.js"></script>
<style>
body {
font-family: sans-serif;
}
svg {
font: 10px sans-serif;
shape-rendering: crispEdges;
}
rect {
fill: #ddd;
}
.axis path, .axis line {
fill: none;
stroke: #fff;
}
.line {
fill: none;
stroke: steelblue;
stroke-width: 3.0px;
}
</style>
<p><label for="zoom-rect"><input type="checkbox" id="zoom-rect"> zoom by rectangle</label>
<table><tr><td> <div id="chart1"> </div> </td></tr></table>
<script>
var zoomRect = false;
d3.select("#zoom-rect").on("change", function() {
zoomRect = this.checked;
});
var Chart = function( _width, _height, _anchor )
{
var self = this;
this.anchor = _anchor;
this.margin = {top: 0, right: 12, bottom: 12, left: 36},
this.width = _width - this.margin.left - this.margin.right,
this.height = _height - this.margin.top - this.margin.bottom;
this.data = [ {x:0 , y:0},
{x:this.width*0.25, y:this.height},
{x:this.width*0.5 , y:this.height/2},
{x:this.width*0.75, y:this.height},
{x:this.width , y:0} ];
this.xscale = d3.scale.linear()
.domain([0, this.width])
.range([0, this.width]);
this.yscale = d3.scale.linear()
.domain([0, this.height])
.range([this.height, 0]);
this.xAxis = d3.svg.axis()
.scale(this.xscale)
.orient("bottom")
.tickSize(-this.height);
this.yAxis = d3.svg.axis()
.scale(this.yscale)
.orient("left")
.ticks(5)
.tickSize(-this.width);
this.zoom = d3.behavior.zoom().x(this.xscale).y(this.yscale).on("zoom", this.refresh);
this.svg = d3.select(this.anchor).append("svg")
.attr("width", this.width + this.margin.left + this.margin.right)
.attr("height", this.height + this.margin.top + this.margin.bottom)
.append("g")
.attr("transform", "translate(" + this.margin.left + "," + this.margin.top + ")")
.call(this.zoom)
.append("g")
.on("mousedown", function() {
if (zoomRect)
{
d3.event.stopPropagation();
}
})
.on("mousemove", function() {
if (zoomRect)
{
d3.event.stopPropagation();
}
});
this.svg.append("rect")
.attr("width", this.width)
.attr("height", this.height);
this.line = d3.svg.line()
.x(function (d) { return self.xscale(d.x) } )
.y(function (d) { return self.yscale(d.y) } )
this.path = this.svg.append("path")
.attr("class", "line")
.datum(this.data)
.attr("d", this.line);
this.svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + this.height + ")")
.call(this.xAxis);
this.svg.append("g")
.attr("class", "y axis")
.call(this.yAxis);
}; // Chart
Chart.prototype.refresh = function() {
console.log("this=" + this);
console.log("self=" + self);
console.log("this.svg=" + this.svg);
console.log("self.svg=" + self.svg);
self.svg.select("path").attr("d", self.line );
self.svg.select(".x.axis").call(self.xAxis);
self.svg.select(".y.axis").call(self.yAxis);
}
var charts = [];
charts.push( new Chart( 760, 400, "#chart1"));
for( var i = 0; i < charts.length; ++i ) {
charts[ i ].refresh();
}
</script>
谢谢。
答案 0 :(得分:2)
this
是保留关键字,self
不是。 Self通常用于在函数内关闭this的值,该函数可能不会在对象本身上调用。但是,在刷新函数中执行console.log(this)
会显示它确实是Chart
对象。
在该功能中使用this
,而不是自我;或者执行这一行(虽然它是多余的)
var self = this;
编辑:虽然自我不是保留字,window.self
是全局属性。因此,为什么self
本身,没有其他背景,window
编辑2: 此行将导致所述错误
this.zoom = d3.behavior.zoom().x(this.xscale).y(this.yscale).on("zoom", this.refresh);
特别是,它是zoom事件的绑定。从the wiki开始,函数将具有
以与其他运算符函数相同的方式调用指定的侦听器,传递当前数据d和索引i,将此上下文作为当前DOM元素。
(强调我的)。
您需要通过Chart对象代理事件,因此将绑定更改为以下内容:
this.zoom = d3.behavior.zoom().x(this.xscale).y(this.yscale).on("zoom", function() {
self.refresh();
});